How do you memcpy a custom class?

Pages: 12
My teacher wants me to use memcpy to copy one of three derived classes.

The 3 classes differ in the number of integers they have, and they all have a char string of up to 100 chars.

Here's what I have so far, but it doesn't work. It copies my text string fine, but only copies one of the two integers.

1
2
				*sym = (OP *) malloc(sizeof(char[LISTLEN]) + sizeof(int) * 2);
				memcpy(*sym, stack[numberOfStackElements-1], sizeof(stack[numberOfStackElements-1]) + sizeof(int)*2);



I find that when I change the 2 to a 3, it works. But I don't understand why that is.

Thanks in advance! =)
Why are you not using new and copy constructors?!?

The homework assignment stated:

"Each case will have a malloc statement which assigns new memory to the argument pointer and a memcpy statement to fill that new memory"

:-/

And I'm also getting this error:

malloc: *** error for object 0xc0000003: Non-aligned pointer being freed

When I try to free the sym like this:

free((void *) stack[numberOfStackElements - 1]);
Last edited on
You aren't supposed to use memcpy() on the class.
You are supposed to use it on the class's data.

There is a significant difference.
EDIT:

I just saw Duoas post now -- could it be that I was misunderstanding the assignment? I find that likely, since memcpying and mallocing is class is seriously poor practice.

It makes a lot more sense that you and I are just misunderstanding the assignment.

Can you post the full assignment so we can see exactly what he's asking you to do?
Last edited on
Thanks for the fast reply.

I think my teacher did this because all the other objs were created with malloc, and you can't "free" an obj created with "new" (right?).

Also, why is mallocing a class bad? I don't really understand.


Regardng the freeing issue:

I declared stack like this:

baseClass *stack[5];

and I assigned stack values like this:

1
2
baseClass sym(value);
stack[0] = &sym;


For some reason, I'm still getting the error when I call:

delete stack[0];

The destructor for baseClass frees a char string. I have no idea why I'm still getting this error:
malloc: *** error for object 0xc0000003: Non-aligned pointer being freed

When I was in the debugger, the destructor freed the char string fine, with no error. But, an error prints as soon as I step out of the destructor. :-/
It's a 8 part assignment. I'll just copy and paste the relevant part:

Class symbolStack:

Data members:

An array of SYMBOL pointers of length LISTLEN. This will be the stack of operators used during the translation.
An int telling how many elements are currently in the stack.

Function members:

A constructor. The constructor function has no arguments. It sets the number of elements in the stack to 0 indicating that the stack is empty when first created.

A print function. The print function has no arguments. It prints a suitable message if the stack is empty. Otherwise it prints the elements of the stack one per line, starting at the top level of the stack.

A push function. The push function has one argument – a pointer to SYMBOL. If the stack is full, do nothing and return SYM_LIST_FULL. Otherwise, push the argument onto the stack and return 0.
A function to return a copy of the top level of the stack. The argument of this function is of type pointer to pointer to SYMBOL, i.e., SYMBOL **s. If the stack is empty, do nothing and return SYMBOL_NOT_FOUND. Otherwise, make a copy of the top level element, assign the argument to point to the copy, and return 0. Because we are implementing a general stack that can hold variables, constants and operators, this function must first retrieve the name of the top-level element and test to see what kind of object the top-level element is. Only then can this function malloc the right amount of memory to hold the new object. Therefore, this function will have three cases. Each case will have a malloc statement which assigns new memory to the argument pointer and a memcpy statement to fill that new memory with the data occurring in the top level.

A pop function. This function has no arguments. If the stack is empty, this function returns SYMBOL_NOT_FOUND. Otherwise, decrement the number of elements in the stack and return 0.
Last edited on
I think my teacher did this because all the other objs were created with malloc, and you can't "free" an obj created with "new" (right?).


Right. new->delete, and malloc->free. Don't mix and match.

Your teacher probably shouldn't even be telling you about malloc. There's very little reason to use it in C++. The only time I'd consider using it is if I'm writing my own new implementation (in which case I can't use new).

Also, why is mallocing a class bad? I don't really understand.


Because it doesn't call the constructor. It only allocates memory. Likewise, free doesn't call the dtor, it only frees the memory.

For some reason, I'm still getting the error when I call:


You shouldn't be deleting something you didn't make with new. That's why it's giving you an error.

stack[0] wasn't made with new, so don't delete it.



And yeah -- your teacher is telling you to malloc/memcpy objects. I really would have to recommend you don't do this, but since your assignment is telling you to do it, I guess you have no choice.

ANYWAY

you're better off doing sizeof() on the actual class rather than trying to sizeof() each individual member:

1
2
YourClass* foo = (YourClass*)malloc( sizeof(YourClass) );
memcpy( foo, src_object, sizeof(YourClass) );
Last edited on
Do these SYMBOLs have non-static member functions or are they just structs (PODs in C++ terminology)?
Thanks so much, Disch.

And PanGalatic:

I don't really know what that means :(. But, there's a char array in there (of variable size), and 2 ints.

I'm currently doing this:

*sym = (OP *) malloc(sizeof(OP));
memcpy(*sym, stack[numberOfStackElements-1], sizeof(OP) + strLength);

Is that right?
Not quite.

Why would you add strLength to the size of OP? You're just copying a single OP, right?
Disch is absolutely right. In general, one should not be using malloc()/memcpy/free() with C++ objects. There are times that it is permissible, but you have not been taught that yet. (And I have yet to see a compelling case as to why you would break this rule in this case.)

The general rule is you should be taught the rules before you are taught how and when to break them.

Based on the collective experience of the folks here, if your teacher is doing this, your teacher probably does not know the C++ language well enough to be teaching it.

You might have your teacher comment on this thread. We'd like to get teacher involvement on this board. Because, based on many of the other questions and projects we see students working on here, the C++ teaching profession needs some help.
I should tone down my posts -- if the teacher shows up here he probably would be offended by my last post XD.

I don't know why, I just get overly bitter and hostile sometimes.

*goes back to edit original post*

Sorry ShooperMAN's teacher! I welcome your contribution to this thread!
@Disch: I certainly get the same way sometimes. I sometimes will write what I feel, then go back and edit my content to read what I really mean without trying to offend.

The first thought that popped in my head when I read the first line of ShooperMAN's post was none to pretty. "Or this could be a graduate-level course where you are learning some funky cool shit" was the second thought. (Knowing full well the odds of that was really low considering this is the "beginner" board.)
Haha, I don't think I should show him this thread. Maybe after I get a grade in the course =D

I'm taking an Introduction to Computer Programming course, and we started off learning C. Perhaps this is why he felt like sticking with the malloc statement. Or maybe he wanted us to further understand the concept of memory, and the size different classes require.

I'm still not sure why memcpy is bad practice (besides the fact that it's error prone and more difficult to do). Does it make the program more prone to random memory-related errors?



I have another problem though. Everything is running fine, but when the program ends, I'm getting the double free error. I'm fairly sure this is because I declared two symbolLists, and XCode is trying to free both of them. The two symbolLists share 4 identical (not in memory) SYMBOLs, and I'm getting 4 double free errors.

Here's a link to my program. I would really really appreciate it if someone could take a look at it.
https://www.yousendit.com/download/MVNlb2VBMm1OMUIzZUE9PQ

Oh, and if you guys are wondering why the hell I'm on a Mac using XCode: I learned programming by making apps for the iPhone, and I've grown pretty familiar to the XCode IDE, and its autocompletion stuff. Tried Visual Studios Express, and didn't like it too much. I'm sure if I tweaked it though it would be fine.

However, I used the malloc and memcpy statement to copy the SYMBOL, and add to the other symbolList, so I don't see why I'm getting a double free error.
ShooperMAN wrote:
Haha, I don't think I should show him this thread. Maybe after I get a grade in the course =D


If he grades you down for showing him what you found while looking for help, then I don't think he should be teaching.

memcpy() is bad practice because it is error prone and more difficult to do. For example, if you have some overlapping arrays or something, it can do some weird stuff.

For posting large code segments, you can use pastebin.com, although that limits you to putting all of the stuff in one file IIRC.

I'm guessing that the error is because when you memcpy() each class/struct, you are copying the pointers to your arrays as well, resulting in two pointers to the same array, and when the objects get destructed, then it is freeing the pointed memory twice.
I suppose. But here's the thing: I haven't been going to class because I had to go back home for some urgent stuff. He might have mentioned that using memcpy is just for this class's purpose, and that we shouldn't use it regularly. I think he's a fairly decent professor. Has been teaching at Northwestern for over 30 years--how could he not be? =)


I understand my problem though. The arrays hold objects which contain a pointer to a string. XCode is trying to free the same string twice.

How can I solve this problem though? Should I make it so that my class holds a string instead of a pointer to one?
Anyone? Sorry about the rush but I need to finish this assignment soon. :-/
Nevermind, I figured it out.

Thanks for all the help.
I think that there has been some unjust criticism of the professor here -- don't be too hasty to judge. As I said in my prior post, he only wants you dynamically allocate and free the class's data -- which is a perfectly normal and acceptable thing to do.

According to your assignment description, your class is supposed to manage a stack of symbols. The stack is implemented as a dynamic array of said symbols. For the memory, you are supposed to use malloc() and free(). In C++, the alternative is new[] and delete[], but that is, for this assignment, a matter of fluff. Use what your professor instructs you to use.

The trick with the class is to manage the copy constructor, assignment operator, and destructor properly, so that you never have more than one pointer to the same malloc()ed data.

Glad you got it working.
Pages: 12