I'm curious as to why free(myWord->w) would be an invalid pointer? I allocate memory to it, so shouldn't I free it as well? or does freeing a struct also free all of its fields?
New to C so any insight on the world of pointers is much appreciated!
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct word {
char *w;
} WORD;
void setWord(char **f);
int main() {
WORD *myWord = malloc(sizeof(WORD));
myWord->w = malloc(6);
strcpy(myWord->w, "hello"); // set to "hello"
setWord(&(myWord->w)); // set to "bagel"
free(myWord->w); /* munmap_chunk(): invalid pointer. Aborted (core dumped) */
free(myWord);
return 0;
}
void setWord(char **F) {
*F = "bagel";
}
*F = "bagel"; is not how you assign a string. Instead the code overwrite the value of the pointer myWord->w so when you call free, it's no longer the correct pointer value.
To see that the pointer change, try this:
printf("%p\n", (void*)myWord->w);
setWord(&(myWord->w)); // set to "bagel"
printf("%p\n", (void*)myWord->w);
Consequently, the free call will fail as the pointer-value isn't the one you got from the malloc.
So instead of *F = "bagel"; use
strcpy(*F, "bagel"); // NOT: *F = "bagel"
Further you don't need to pass the address of w. Simply do:
void setWord(char *F) {
strcpy(F, "bagel");
}
and call it like:
setWord(myWord->w);
And...
I allocate memory to it, so shouldn't I free it as well? or does freeing a struct also free all of its fields?
Yes, you must free it.
No, free of a struct does not free members automatically. You must do that.
Related
We have pointers inside a struct, do we need to initialize the pointers inside the struct?
I have tried the code below, include this sentence below or not, the code all run well.
(Could some experts give help here? and I read some code, and found seems sometimes initialized, sometimes not, so confused and search/ask here.)
The answer in this link seems not mentioned initialize this pointer inside struct. initializing-a-member-of-a-structure-with-pointers-c
#include "stdio.h"
#include "stdlib.h"
struct part{
int num;
char *name;
};
int main()
{
struct part *p = (struct part*)malloc(sizeof(struct part));
//Include this or not, this code all run well
p->name = (char*)malloc(sizeof(char));
p->num = 1;
p->name = "ss";
printf("%d, %s\n", p->num, p->name);
return 0;
}
No, you should not do that, you are creating a memory leak, because you allocate memory and then forget the pointer value and don't free it.
To remove the memory leak:
p->name = malloc(1); //sizeof char is 1 by definition, and cast not needed
free(p->name);
p->name = "ss";
However, if you look at that, it should be clear that allocating 1 byte of memory, then immediately freeing it, is pointless.
Perhaps you want a copy of the string?
const char *initdata = "ss";
p->name = malloc(strlen(initdata)+1);
strcpy(p->name, initdata);
// Remember to free this at some point
Alternatively, you could use initialize with the string literal, but then you should have const char pointer because string literals are read-only:
struct part{
int num;
const char *name;
};
I use free() to free the structure I allocated before, and I want to test if they have successfully free, but I get only one of them free why?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student{
char *name;
struct student *next;
}student;
int main(int argc, const char * argv[]) {
student *a=malloc(sizeof(student));
a->name="echo";
student *b=malloc(sizeof(student));
b->name="harry";
a->next=b;
b->next=NULL;
free(a);
free(b);
printf("%s\n", a->name);
printf("%s\n", b->name);
return 0;
}
and I got this output.Why?
(null)
harry
Program ended with exit code: 0
You can't "test" if they have successfully been freed, trying to access any memory that has been freed is undefined behavior, instead of testing just accept and move on.
You have freed the memory but that doesn't mean the pointer has been invalidated by the system. In your second case, the data where it pointed to has not yet been re-used so printf finds it and can print.
In the first case the memory has been re-used or reset. print finds a null pointer.
In the second case the memory has not yet been re-used: printf finds it and can print it.
But this undefined behavior and anything could have happened.
You can better use free along with setting the variable to NULL.
free(b);
b = NULL;
free(a);
a = NULL;
When you call free, the variable is marked for recollection. And when that recollection of the memory allocated should happen is up to the underlying OS. You should not access the freed block.
For example I have this structure:
typedef struct{
char *var = (char*)malloc(20*sizeof(char));
} EXAMPLE;
EXAMPLE *point = (EXAMPLE*)malloc(sizeof(EXAMPLE));
My first question is, will the memory allocated inside the structure only be allocated when I allocate memory for the EXAMPLE pointer?
My second question, when I use free(point) will the memory allocated for var also be freed?
With this struct:
typedef struct{
char *var;
} EXAMPLE;
Remember that when you allocate space for the struct, you're allocating space only for the char * pointer. This pointer just points to memory elsewhere. When you free() the struct, you're just freeing the char * pointer, not the actual memory that it points to.
As such, if you make this struct and then malloc() space for the string you want var to point to, you need to free() the string as well as free()ing the struct.
Some code demonstrating how this might work:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
char *var;
} EXAMPLE;
int main(int argc, char *argv[]) {
// malloc() space for the EXAMPLE struct.
EXAMPLE *point = malloc(sizeof(EXAMPLE));
// malloc() space for the string that var points to.
point->var = malloc(20 * sizeof(char));
// Copy "Hello!" into this memory (care with strcpy).
strcpy(point->var, "Hello!");
// Print it, it works!
printf("point->var is: %s\n", point->var);
// Free stuff.
free(point->var);
free(point);
return 0;
}
Also note that we don't cast the result of malloc(), in C you're not meant to. Also note that we free() point->var first before point. This is important because if we free() point first, we lose the pointer to point->var, and we have a memory leak.
I'm ignoring the non-compiling code since the question is pretty clear without it ;-)
No. free() does not know the structure of what it is pointing at,so it just frees one "block". If that block has pointers to other malloced memory then they are leaked (unless there is a pointer to those blocks somewhere else).
This program is crashing. Please tell me what's wrong with it. When I use an array instead of a pointer like Name[12] in the structure it doesn't crash. I guess there is some problem in dynamic memory allocation. Help please.
#include <stdio.h>
struct struct_tag
{
int number;
char *Name;
} struct_name;
main()
{
struct_name.number = 34;
char *Name = (char *) malloc(sizeof(char));
strcpy(struct_name.Name,"A");
printf("%d", struct_name.number);
}
You're allocating a single character:
char *Name = (char *) malloc(sizeof(char));
And then never using that memory for anything. You meant to allocate memory for struct_name.Name, undoubtedly. But even if you had done so, you're then filling it with two characters ('a' and '\0'):
strcpy(struct_name.Name,"A");
which will cause an entirely different bug.
You want to say:
struct_name.Name = malloc( 2 );
Since (a) you shouldn't cast the result of malloc() and (b) sizeof(char) is always 1 and (c) you need room for the 0 at the end of your string.
For errors:
You are allocating memeory for *Name however you are not allocating
memory for struct_name.Name. So first thing is you need to allocate memory for struct_name.Name
As you already know that you'll be storing "A" in
struct_name.Name you should allocate memory for 2 char.("A" is string i.e 'A' and '\0')
For warnings:
If you want to use strcpy function include string.h in your code.
Also if you are using malloc include stdlib.h in your code.
Try this fixed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct struct_tag
{
int number;
char *Name;
}struct_name;
int main()
{
struct_name.number = 34;
struct_name.Name = malloc(sizeof(char)*2); // As you will store "A"
strcpy(struct_name.Name,"A");
printf("%d \t", struct_name.number);
printf("%s \n", struct_name.Name);
return 0;
}
first look code carefully.
char *Name = (char *) malloc(sizeof(char));
strcpy(struct_name.Name,"A");
Hare for what you allocated memory (char *Name) and in which you copied string(struct_name.Name)?
here you not allocate memory for struct_name.Name. Also you have allocate memory for one character and you tried to copy two characters.('A' and '\0').
It should be
struct_name.Name = malloc(2);
I am allocating some memory in a function name myalloc() and using and freeing it in main().
I am using double pointer to do this, here is the code which works fine,
//Example # 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void myalloc( char ** ptr)
{
*ptr = malloc(255);
strcpy( *ptr, "Hello World");
}
int main()
{
char *ptr = 0;
myalloc( &ptr );
printf("String is %s\n", ptr);
free(ptr);
return 0;
}
But following code does not work and gives segmentation fault.
I think this is another way to use double pointers.
//Example # 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void myalloc( char ** ptr)
{
*ptr = malloc(255);
strcpy( *ptr, "Hello World");
}
int main()
{
char **ptr = 0;
myalloc( ptr );
printf("String is %s\n", *ptr);
free(*ptr);
return 0;
}
Please clarify me, why it is giving me seg fault in second example.
Note: Language = C, Compiler = GCC 4.5.1, OS = Fedora Core 14
Also, i know that there are some question already been asked related to memory allocation using double pointers, but they don't address this issue, so please don't flag it as repetitive question.
char **ptr = 0;
*ptr = malloc(255);
tries to write the pointer returned by malloc to the address(of type char*) pointed to by ptr. The address turns out to be ... 0, which is not writable memory.
ptr should point to an address you can write to. You can do one of the following:
char *stackPtr; // Pointer on the stack, value irrelevant (gets overwritten)
ptr = &stackPtr;
// or
char **ptr = alloca(sizeof(char*)); // Equivalent to above
// or
char **ptr = malloc(sizeof(char*)); // Allocate memory on the heap
// note that ptr can be 0 if heap allocation fails
char **ptr = 0;
foo( ptr );
You are passing the value that ptr points to. But you havent pointed ptr to anything yet.
*ptr = malloc(255);
Now you are assigning some memory to that "nothing". So this wont work, and will segfault.
Why are you saying that this is another way of using double pointers? I apologise if I am wrong, but I guess you worked with type of program in Turbo-C earlier?
In the second case, you are passing the value of main's ptr, which is 0 (NULL), to myalloc()'s ptr. myalloc() then tries to dereference its null pointer, ptr.