Runtime error in pointer to structure - c

I am doing unit testing using google C++ testing tools. I am a novice C programmer as well as tester.
The following is my code snippet :
TEST_F (def_fix, SR_M_T) {
I_M_S * arg;
RM__S_F_R_T* message_data;
char mT[MAX_M_T_LENGTH] = "data";
strcpy(message_data->mT,mT);
message_data->rUID[0] = '\0';
message_data->uT[0] = '\0';
unsigned char buffer[sizeof(RM__S_F_R_T)+2];
memcpy(&buffer[2],message_data,sizeof(RM__S_F_R_T));
buffer[0] = 1; //This assignment is not important for this test
buffer[1] = 2; //This assignment is not important for this test
arg->payload_data = buffer;
handleSR(arg);
}
What the above does is creating an incoming message. This incoming message arg is to be used as parameter to call a function handleSR (void *).
def_fix is a default fixture class which contains SetUp() and TearDown() and nothing fancy in them.
RM__S_F_R_T is a structure which contains and 3 strings.
I_M_S is a structure containing a pointer to RM__S_F_R_T.
When I google test this, it gives a segmentation error. However when I change:
RM__S_FR_R_ * message_data; to RM__S_FR_R_ message_data;and use . operator instead of -> operator, things tend to work. Can anyone explain?

These two statements:
RM__S_F_R_T* message_data;
strcpy(message_data->mT,mT);
are the culprit. You never initialise the RM__S_F_R_T (who designed this thing?!) pointer. When not using it as a pointer, you create an instance on the stack that you can use.
To fix either don't use a pointer (you already found that out), or allocate memory:
message_data = malloc(sizeof(RM__S_F_R_T));
don't forget to free(message_data) when you are done with the instance, or you'll leak memory.

It's because you declare message_data to be a pointer, but don't point it at anything. So then it will point to a random memory location, causing undefined behavior when you dereference it.
Either declare it as not a pointer, or allocate memory for it.

You have not provided memory to RM__S_F_R_T*.Use message_data after
message_data = (RM__S_F_R_T*)malloc(sizeof(RM__S_F_R_T));

message_data doesn't point to anything. You need to pass an initialised RM__S_F_R_T struct pointer to your function as an argument or initialise it inside the function itself.
Further, I presume message_data->mT is a char pointer. It's not pointing to anything currently.
You can assign space for it using malloc, or if it's a char array then make sure it's big enough to hold mT into it (provided its struct is already initialised).
The above applies to all of message_data's members.
As the other posters have already mentioned, don't forget to free() anything you have malloc()-ed.

Initialize I_M_S * arg and RM__S_F_R_T* message_data:
I_M_S * arg = malloc(sizeof(I_M_S));
RM__S_F_R_T* message_data = malloc(sizeof(RM__S_F_R_T));
Also, make sure you don't use these allocated pointers after the scope of function TEST_F() because you assign arg->payload_data = buffer where scope of localized variable buffer ends after the function TEST_F().
And so, free these pointers before you leave TEST_F():
free(arg);
free(message_data);

Related

malloc preventing garbage from being printed?

Program was programmed in C and compiled with GCC.
I was trying to help a friend who was trying to use trying to (shallow) copy a value that was passed into a function. His the value was a struct that held primitives and pointers (no arrays or buffers). Unsure of how malloc works, he used it similar to how the following was done:
void some_function(int rand_params, SOME_STRUCT_TYPEDEF *ptr){
SOME_STRUCT_TYPEDEF *cpy;
cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));// this line makes a difference?!?!?
cpy = ptr;// overwrites cpy anyway, right?
//prints a value in the struct documented to be a char*,
//sorry couldn't find the documentation right now
}
I told him that the malloc shouldn't affect the program, so told him to comment it out. To my surprise, the malloc caused a different output (with some intended strings) from the implementation with the malloc commented out (prints our garbage values). The pointer that's passed into the this function is from some other library function which I don't have documentation for at the moment. The best I can assume it that the pointer was for a value that was actually a buffer (that was on the stack). But I still don't see how the malloc can cause such a difference. Could someone explain how that malloc may cause a difference?
I would say that the evident lack of understanding of pointers is responsible for ptr actually pointing to memory that has not been correctly allocated (if at all), and you are experiencing undefined behaviour. The issue is elsewhere in the program, prior to the call to some_function.
As an aside, the correct way to allocate and copy the data is this:
SOME_STRUCT_TYPEDEF *cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));
if (cpy) {
*cpy = *ptr;
// Don't forget to clean up later
free(cpy);
}
However, unless the structure is giant, it's a bit silly to do it on the heap when you can do it on the stack like this:
SOME_STRUCT_TYPEDEF cpy = *ptr;
I can't see why there difference in the print.
can you show the print code?
anyway the malloc causes memory leak. you're not supposed to allocate memory for 'cpy' because pointer assignment is not shallow-copy, you simply make 'cpy' point to same memory 'ptr' point by storing the address of the start of that memory in 'cpy' (cpy is mostly a 32/64 bit value that store address, in case of malloc, it will store the address of the memory section you allocated)

return string pointer from function in C

Here is my code:
TCHAR *sResult = (TCHAR *) calloc(16384+1, sizeof(TCHAR));
sResult = (TCHAR *) GetValueFromFile(sFilename,L"Dept",L"Names"); // #1
_tcscpy(sResult,(TCHAR *) GetValueFromFile(sFilename,L"Dept",L"Names"); // #2
Function:
TCHAR *GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames)
{
...
}
Which is correct to do? #1 or #2?
Thanks everyone.
Edit #1:
I'm using VS2008 in .cpp files, but really just C code.
I just need to open a file in GetValueFromFile and send the return string back. Should I be allocating memory in GVFF and freeing it in my program?
main()
{
TCHAR *sResult;
DWORD dwRetVal = GetValueFromFile(sFile,L"Dept",L"Name", &sResult);
...
free(sResult);sResult=NULL;
}
Like this?
DWORD GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames, TCHAR ** sValueData)
{
dwL = GetStringDataLength(…)
*sValueData = (TCHAR *) calloc(dwL+1, sizeof(TCHAR));
_tcscpy_s(sValueData,dwL,sDataFromFile);
}
Well, first off, this is unnecessary in case 1 and leads to a problem:
TCHAR *sResult = (TCHAR *) calloc(16384+1, sizeof(TCHAR));
I don't know where 16384+1 is coming from, so I'll assume that's "correct" for now, but you proceed to set the pointer to another value in the very next line. That, my friend, is a memory leak. Why are you allocating memory that you don't need?
Your question really boils down to the implementation of GetValueFromFile. If that function returns a pointer (which it does) then it should certainly be a valid pointer and you are responsible for deallocating it (probably. Again, depends on the implementation).
There is no need to create a copy unless you actually need a copy. There is no "right" or "wrong" here from the information you have given us, we need to know the details of GetValueFromFile.
Per your edit:
That function does not return anything. At all. It's signature says it returns a DWORD, not a TCHAR*. It is obviously different than your first example as it initializes the pointer as an output argument (the 4th one), but that is not how you are calling it in your original example.
I am just further confused now, but if the function initializes the pointer then you need only declare (no memory allocation outside of the function) the pointer and pas in its address.
Given
DWORD GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames, TCHAR ** sValueData)
Then the proper way to pass your pointer in is:
TCHAR *result;
GetValueFromFile(filename, dept, names, &result);
The function initializes your result variable to point to a valid location. Do not forget that you are now responsible for deallocating it!
1 clearly is not correct. You start by allocating space with calloc, but then you overwrite the point to that space with the return from GetValueFromFile. Assuming no intervening code that saves that pointer somewhere else, this means you no longer have access to the memory you allocated, so you can no longer access or free it. In short, a big memory leak.
Depending on how GetValueFromFile allocates the memory to which it returns a pointer, #2 might be just as bad, but the code you posted doesn't tell us enough to know. If it returns something like a pointer to a statically allocated buffer, then chances are it's correct (for some definition of correct). If it's allocating space with something like malloc or calloc, and expecting the client code to release that when needed, then it has a problem similar to that in #1.
Note that the "for some definition of correct" basically translates to something like: "wrong the minute you have more than one thread, or any need for reentrancy". Given the current ubiquity of multicore and multiprocessor systems, that definition is pretty narrow now, and getting narrower all the time.

C char* pointers pointing to same location where they definitely shouldn't

I'm trying to write a simple C program on Ubuntu using Eclipse CDT (yes, I'm more comfortable with an IDE and I'm used to Eclipse from Java development), and I'm stuck with something weird. On one part of my code, I initialize a char array in a function, and it is by default pointing to the same location with one of the inputs, which has nothing to do with that char array. Here is my code:
char* subdir(const char input[], const char dir[]){
[*] int totallen = strlen(input) + strlen(dir) + 2;
char retval[totallen];
strcpy(retval, input);
strcat(retval, dir);
...}
Ok at the part I've marked with [*], there is a checkpoint. Even at that breakpoint, when I check y locals, I see that retval is pointing to the same address with my argument input. It not even possible as input comes from another function and retval is created in this function. Is is me being unexperienced with C and missing something, or is there a bug somewhere with the C compiler?
It seems so obvious to me that they should't point to the same (and a valid, of course, they aren't NULL) location. When the code goes on, it literally messes up everything; I get random characters and shapes in console and the program crashes.
I don't think it makes sense to check the address of retval BEFORE it appears, it being a VLA and all (by definition the compiler and the debugger don't know much about it, it's generated at runtime on the stack).
Try checking its address after its point of definition.
EDIT
I just read the "I get random characters and shapes in console". It's obvious now that you are returning the VLA and expecting things to work.
A VLA is only valid inside the block where it was defined. Using it outside is undefined behavior and thus very dangerous. Even if the size were constant, it still wouldn't be valid to return it from the function. In this case you most definitely want to malloc the memory.
What cnicutar said.
I hate people who do this, so I hate me ... but ... Arrays of non-const size are a C99 extension and not supported by C++. Of course GCC has extensions to make it happen.
Under the covers you are essentially doing an _alloca, so your odds of blowing out the stack are proportional to who has access to abuse the function.
Finally, I hope it doesn't actually get returned, because that would be returning a pointer to a stack allocated array, which would be your real problem since that array is gone as of the point of return.
In C++ you would typically use a string class.
In C you would either pass a pointer and length in as parameters, or a pointer to a pointer (or return a pointer) and specify the calls should call free() on it when done. These solutions all suck because they are error prone to leaks or truncation or overflow. :/
Well, your fundamental problem is that you are returning a pointer to the stack allocated VLA. You can't do that. Pointers to local variables are only valid inside the scope of the function that declares them. Your code results in Undefined Behaviour.
At least I am assuming that somewhere in the ..... in the real code is the line return retval.
You'll need to use heap allocation, or pass a suitably sized buffer to the function.
As well as that, you only need +1 rather than +2 in the length calculation - there is only one null-terminator.
Try changing retval to a character pointer and allocating your buffer using malloc().
Pass the two string arguments as, char * or const char *
Rather than returning char *, you should just pass another parameter with a string pointer that you already malloc'd space for.
Return bool or int describing what happened in the function, and use the parameter you passed to store the result.
Lastly don't forget to free the memory since you're having to malloc space for the string on the heap...
//retstr is not a const like the other two
bool subdir(const char *input, const char *dir,char *retstr){
strcpy(retstr, input);
strcat(retstr, dir);
return 1;
}
int main()
{
char h[]="Hello ";
char w[]="World!";
char *greet=(char*)malloc(strlen(h)+strlen(w)+1); //Size of the result plus room for the terminator!
subdir(h,w,greet);
printf("%s",greet);
return 1;
}
This will print: "Hello World!" added together by your function.
Also when you're creating a string on the fly you must malloc. The compiler doesn't know how long the two other strings are going to be, thus using char greet[totallen]; shouldn't work.

Determining whether a struct member has valid data before trying to free() it

I am using the code below to free up malloced memory in the meshes struct, which contains triangleArrays and faces.
This crashes because not every position in the struct has data. What I want to do is only call free if the struct contains data at that member of the array. However using if (self.meshes[meshIdx].triangleArrays[triangleArrayIdx].faces !=NULL) does not seem to work.
for (int meshIdx = 0; meshIdx <=meshTriangleArrays; meshIdx ++) {
for (int triangleArrayIdx = 0; triangleArrayIdx <=1; triangleArrayIdx ++) {
if (self.meshes[meshIdx].triangleArrays[triangleArrayIdx].faces !=NULL) {
free(self.meshes[meshIdx].triangleArrays[triangleArrayIdx].faces);
}
}
}
Calling free on a null pointer is actually fine.
You haven't given enough code to fully diagnose this problem, but a few things to look at:
You need to make sure that self.meshes[...].triangleArrays[...].faces is always initialized, either by a call to malloc (or whatnot), or by setting it to NULL. Otherwise it can (and likely will) be a random garbage pointer that you don't have permission to free.
You need to make sure that all the different self.meshes[...].triangleArrays[...].faces pointers are distinct pointers. You are only allowed to call free exactly once on a malloc'd pointer. For example, something like this:
int * p = (int *) malloc(sizeof(int));
free(p);
free(p); // undefined behavior
can cause a crash.
The below code crashes because not every position in the struct has data.
No, it doesn't crash due to passing a NULL pointer to free(). If you pass in a NULL pointer nothing happens, see the documentation.
What error is being thrown? Show us your initialization code as well, i.e., how are you allocating faces and everything above it? You are likely passing in some bad/uninitialized data to free().
BTW, due to the way you have asked this question I am lead to believe that you think simply declaring an array will fill every element with NULL. This is not the case, they may be filled with anything, and if you pass that to free you will crash (if you're lucky).
How was the triangleArrays array created in the first place? Is it possible that the non-allocated members contain garbage instead of NULL?

Freeing pointers from inside other functions in C

Consider the c code:
void mycode() {
MyType* p = malloc(sizeof(MyType));
/* set the values for p and do some stuff with it */
cleanup(p);
}
void cleanup(MyType* pointer) {
free(pointer);
pointer = NULL;
}
Am I wrong in thinking that after cleanup(p); is called, the contents of p should now be NULL? Will cleanup(MyType* pointer) properly free the memory allocation?
I am coding my college assignment and finding that the debugger is still showing the pointer to have a memory address instead of 0x0 (or NULL) as I expect.
I am finding the memory management in C to be very complicated (I hope that's not just me). can any shed some light onto what's happening?
Yes that will free the memory correctly.
pointer inside the cleanup function is a local variable; a copy of the value passed in stored locally for just that function.
This might add to your confusion, but you can adjust the value of the variable p (which is local to the mycode method) from inside the cleanup method like so:
void cleanup(MyType** pointer) {
free(*pointer);
*pointer = NULL;
}
In this case, pointer stores the address of the pointer. By dereferencing that, you can change the value stored at that address. And you would call the cleanup method like so:
cleanup(&p);
(That is, you want to pass the address of the pointer, not a copy of its value.)
I will note that it is usually good practice to deal with allocation and deallocation on the same logical 'level' of the software - i.e. don't make it the callers responsibility to allocate memory and then free it inside functions. Keep it consistent and on the same level.
cleanup will properly free p, but it won't change its value. C is a pass-by-value language, so you can't change the caller's variable from the called function. If you want to set p from cleanup, you'll need to do something like:
void cleanup(MyType **pointer) {
free(*pointer);
*pointer = NULL;
}
And call it like:
cleanup(&p);
Your code is a little bit un-idiomatic, can you explain a bit better why you want to write this cleanup function?
Yes
Yes
Yes: There is a block of memory magically produced by malloc(3). You have assigned the address of this memory, but not the memory itself in any meaningful way, to the pointer p which is an auto variable in mycode().
Then, you pass p to cleanup(), by value, which will copy the pointer and, using the copy local to cleanup(), free the block. cleanup() then sets it's own instance of the pointer to NULL, but this is useless. Once the function is complete the parameter pointer ceases to exist.
Back in mycode(), you still have pointer p holding an address, but the block is now on the free list and not terribly useful for storage until allocated again.
You may notice that you can even still store to and read back from *p, but various amounts of downstream lossage will occur, as this block of memory now belongs to the library and you may corrupt its data structures or the data of a future owner of a malloc() block.
Carefully reading about C can give you an abstract idea of variable lifetime, but it's far easier to visualize the near-universal (for compiled languages, anyway) implementation of parameter passing and local variable allocation as stack operations. It helps to take an assembly course before the C course.
This won't work as the pointer in cleanup() is local, and thus assigning it NULL is not seen by the calling function. There are two common ways of solving this.
Instead of sending cleanup the pointer, send it a pointer to the pointer. Thus change cleanup() as follows:
void cleanup(MyType** pointer)
{
free(*pointer);
*pointer = NULL;
}
and then just call cleanup(&p).
A second option which is quite common is to use a #define macro that frees the memory and cleans the pointer.
If you are using C++ then there is a third way by defining cleanup() as:
void cleanup(MyType& *pointer)
{
// your old code stays the same
}
There are two questions are here:
Am I wrong in thinking that after
cleanup(p); is called, the contents of
p should now be NULL?
Yes, this is wrong. After calling free the memory pointed by the pointer is deallocated. That doesn't mean that the content pointed by the pointer is set to NULL. Also, if you are expecting the pointer p to become NULL in mycode it doesn't happen because you are passing copy of p to cleanup. If you want p to be NULL in mycode, then you need a pointer to pointer in cleanup, i.e. the cleanup signature would be cleanup(MyType**).
Second question:
Will cleanup(MyType* pointer) properly
free the memory allocation?
Yes, since you are doing free on a pointer returned by malloc the memory will be freed.
It's not just you.
cleanup() will properly clean up your allocation, but will not set the pointer to NULL (which should IMHO be regarded as separate from cleanup.) The data the pointer points to is passed to cleanup() by pointer, and is free()ed properly, but the pointer itself is passed by value, so when you set it to NULL you're only affecting the cleanup() function's local copy of the pointer, not the original pointer.
There are three ways around this:
Use a pointer to a pointer.
void cleanup(struct MyType **p) { free(*p); *p = NULL; }
Use a macro.
#define cleanup(p) do { free(p); p = NULL; } while(0)
or (probably better):
void cleanup_func(struct MyType *p) { /* more complicated cleanup */ }
#define cleanup(p) do { cleanup_func(p); p = NULL; } while(0)
Leave the responsibility of setting pointers to NULL to the caller. This can avoid unnecessary assignments and code clutter or breakage.

Resources