I keep constantly getting a segmentation error with a small portion of code and I have no idea why, I'm using malloc and cant see any reason with that, just as soono as it hits the portion of data, its crashes.
The Data is:
listNode* node = (listNode*)malloc(sizeof(listNode)); <-This is the Line
strcpy(node->entry, string);
node->next = NULL;
Using the struct definition:
typedef struct
{
char* entry;
struct listNode* next;
}listNode;
The data does get freed at one point, however it cannot reach said point.
Thanks for the help!
Are you sure you're crashing on the malloc call? It's much more likely that you're crashing on the strcpy. In fact, the strcpy in this case is almost guaranteed to cause bad behavior, although to be precise the behavior is undefined.
The malloc should succeed as long as you haven't filled up your heap. However, because you called malloc and not calloc, you have no guarantees about the contents of node->entry. The C standard doesn't define what is stored in memory allocated with malloc, so node->entry is filled with garbage. By trying to copy to a bad pointer, your app is crashing for attempting to accessing an incorrect memory address.
Alexey Frunze is 100% correct on the fix - malloc space and change node->entry to point at the newly allocated memory, then copy string into node->entry. This avoids undefined behavior for using an uninitialized pointer, as I described in another SO answer.
You didn't allocate memory for the entry pointer. You're trying to copy your string to a bogus location specified by the uninitialized pointer entry. You might do this instead:
node->entry = malloc(strlen(string) + 1);
strcpy(node->entry, string);
You are not allocating allocate memory for the entry pointer. as while allocationg structure just 4 bytes allocated for *entry pointer
you should do
listNode* node = (listNode*)malloc(sizeof(listNode)); // allocate memory for structure
node->entry = malloc(strlen(string) + 1);// allocate memory for string
strcpy(node->entry, string); //copying strings
now it will run fine
Related
I tried to find the proper way to dynamically allocate memory for a structure that looks like this:
typedef struct myThread {
unsigned int threadId;
char threadPriority;
unsigned int timeSlice;
sem_t threadSem;
} myThread;
I remember, but I'm not sure, that, in some school paper, I saw that the proper way to allocate memory for this case is this one:
myThread *node = (myThread *)malloc(sizeof(myThread *));
I tried that and it worked, but I didn't understand why. Sizeof pointer for my architecture is 8 bytes, so by writing the instruction above, I'm allocating 8 bytes of continuous memory, not enough to hold the information needed in my structure. So I tried to allocate 1 byte of memory, like this:
myThread *node = (myThread *)malloc(1);
And it's still working.
I tried to find the answer for this behavior but I didn't succeed. Why is this working? Besides that, I have few more questions:
Which is the right way to dynamically allocate memory for a structure?
Is that cast necessary?
How is the structure stored in memory? I know that (*node).threadId is equivalent to node->threadId and this confuses me a bit because by dereferencing the pointer to the structure, I get the whole structure, and then I have to access a specific field. I was expecting to access fields knowing the address of the structure in this way: *(node) it's the value for the first element, *(node + sizeof(firstElement)) it's the value for the second and so on. I thought that accessing structure fields it's similar to accessing array values.
Thank you
Later Edit: Thank you for your answers, but I realized that I didn't explained myself properly. By saying that it works, I mean that it worked to store values in those specific fields of the structure and use them later. I tested that by filling up the fields and printing them afterwards. I wonder why is this working, why I can fill and work with fields of the structure for which I allocated just one byte of memory.
The below works in that they allocate memory - yet the wrong size.
myThread *node = (myThread *)malloc(sizeof(myThread *));// wrong size,s/b sizeof(myThread)
myThread *node = (myThread *)malloc(1); // wrong size
Why is this working?
When code attempts to save data to that address, the wrong size may or may not become apparent. It is undefined behavior (UB).
C is coding without training wheels. When code has UB like not allocating enough memory and using it, it does not have to fail, it might fail, now or later or next Tuesday.
myThread *node = (myThread *)malloc(1); // too small
node->timeSlice = 42; // undefined behavior
Which is the right way to dynamically allocate memory for a structure? #M.M
The below is easy to code right, review and maintain.
p = malloc(sizeof *p); //no cast, no type involved.
// or
number_of_elements = 1;
p = malloc(sizeof *p * number_of_elements);
// Robust code does error checking looking for out-of-memory
if (p == NULL) {
Handle_error();
}
Is that cast necessary?
No. Do I cast the result of malloc?
How is the structure stored in memory?
Each member followed by potential padding. It is implementation dependent.
unsigned int
maybe some padding
char
maybe some padding
unsigned int
maybe some padding
sem_t
maybe some padding
I wonder why is this working, why I can fill and work with fields of the structure for which I allocated just one byte of memory.
OP is looking for a reason why it works.
Perhaps memory allocation is done in chunks of 64-bytes or something exceeding sizeof *p so allocating 1 had same effect as sizeof *p.
Perhaps the later memory area now corrupted by code's use of scant allocation will manifest itself later.
Perhaps the allocater is a malevolent beast toying with OP, only to wipe out the hard drive next April 1. (Nefarious code often takes advantage of UB to infect systems - this is not so far-fetched)
Its all UB. Anything may happen.
Since memory allocation in C is quite error prone I always define macro functions NEW and NEW_ARRAY as in the example below. This makes memory allocation more safe and succinct.
#include <semaphore.h> /*POSIX*/
#include <stdio.h>
#include <stdlib.h>
#define NEW_ARRAY(ptr, n) \
{ \
(ptr) = malloc((sizeof (ptr)[0]) * (n)); \
if ((ptr) == NULL) { \
fprintf(stderr, "error: Memory exhausted\n"); \
exit(EXIT_FAILURE); \
} \
}
#define NEW(ptr) NEW_ARRAY((ptr), 1)
typedef struct myThread {
unsigned int threadId;
char threadPriority;
unsigned int timeSlice;
sem_t threadSem;
} myThread;
int main(void)
{
myThread *node;
myThread **nodes;
int nodesLen = 100;
NEW(node);
NEW_ARRAY(nodes, nodesLen);
/*...*/
free(nodes);
free(node);
return 0;
}
malloc reserves memory for you to use.
When you attempt to use more memory than you requested, several results are possible, including:
Your program accesses memory it should not, but nothing breaks.
Your program accesses memory it should not, and this damages other data that your program needs, so your program fails.
Your program attempts to access memory that is not mapped in its virtual address space, and a trap is caused.
Optimization by the compiler transforms your program in an unexpected way, and strange errors occur.
Thus, it would not be surprising either that your program appears to work when you fail to allocate enough memory or that your program breaks when you fail to allocate enough memory.
Which is the right way to dynamically allocate memory for a structure?
Good code is myThread *node = malloc(sizeof *node);.
Is that cast necessary?
No, not in C.
How is the structure stored in memory? I know that (*node).threadId is equivalent to node->threadId and this confuses me a bit because by dereferencing the pointer to the structure, I get the whole structure, and then I have to access a specific field. I was expecting to access fields knowing the address of the structure in this way: *(node) it's the value for the first element, *(node + sizeof(firstElement)) it's the value for the second and so on. I thought that accessing structure fields it's similar to accessing array values.
The structure is stored in memory as a sequence of bytes, as all objects in C are. You do not need to do any byte or pointer calculations because the compiler does it for you. When you write node->timeSlice, for example, the compiler takes the pointer node, adds the offset to the member timeSlice, and uses the result to access the memory where the member timeSlice is stored.
you do not allocate the right size doing
myThread *node = (myThread *)malloc(sizeof(myThread *));
the right way can be for instance
myThread *node = (myThread *)malloc(sizeof(myThread));
and the cast is useless so finally
myThread *node = malloc(sizeof(myThread));
or as said in remarks to your question
myThread *node = malloc(sizeof(*node));
The reason is you allocate a myThread not a pointer to, so the size to allocate is the size of myThread
If you allocate sizeof(myThread *) that means you want a myThread ** rather than a myThread *
I know that (*node).threadId is equivalent to node->threadI
yes, -> dereference while . does not
Having myThread node; to access the field threadId you do node.threadId, but having a pointer to you need to deference whatever the way
Later Edit: ...
Not allocating enough when you access out of the allocated block the behavior is undefined, that means anything can happen, including nothing bad visible immediately
This question already has answers here:
Why do I get different results when I dereference a pointer after freeing it?
(7 answers)
Closed 8 years ago.
I'm trying to understand the how the memory is managed in C. In the sample code below, in the comments I have added my understanding on how the memory is managed.
I would like to know if I'm correct
In the final part of the code, I'm trying to access a part of memory which is already freed. I'm surprised why the compiler did not through any warnings
struct node
{
int keys[2];
int *pkeys;
};
int main()
{
int temp[2] = {10,20}; // creates a temp array in stack
struct node* node = malloc(sizeof(struct node)); //allocates a block of memory on heap pointed by node
node->keys[0]=1;node->keys[1]=2; // assigns values for keys present in heap
node->pkeys = malloc(2*sizeof(int)); // creates a pointer pkeys in heap
node->pkeys = temp; // the pointer pkeys in heap points to the temp array in stack
free(node); // the block of memory on heap pointed by node is freed
node->keys[0] = 9; //**Why does the compiler ignore that I'm accessing freed memory?**
}
The compiler in C does not do that sort of checking. If gives enough rope to hang yourself.
It is up to you to do the checks. That is also true for bounds checking of arrays.
Also you need to note that malloc/free does not always have to beg/give to the OS. That means it may still be accessible by the process without seg fault.
The compiler does not check for illegal memory access and your program will cause undefined behaviour or may even crash (segmentation fault). The behaviour is unpredictable and next time you run your program, it may crash.
Few things about your code:
The signature of main should either be int main(void) or int main(int argc, char *argv[]).
The comment for this statement is wrong.
node->pkeys = malloc(2*sizeof(int)); // creates a pointer pkeys in heap
You created the pointer pkeys when you allocated memory and made node point to it. This statement is dynamically allocating memory for array of 2 ints and making pkeys point to it. So when you do node->pkeys = temp, you lose handle on the dynamically allocated array and will cause memory leak. So before reassigning pkeys, you must free the memory it points to.
free(node->pkeys);
// now reassign node->pkeys
The space allocated to node is freed but node still points to the same location. So it is still accessible. But if you are unlucky (that is the OS reused the memory for its own purposes) you will get a segmentation fault.
I'm in the middle of a project and I'm trying to use malloc() and realloc(). I know when I malloc, it works, but when I use realloc, it doesn't change the amount of alloced memory at all. I've always though that realloc will re-allocate your already malloced memory.
Here is what I have:
This include:
#include <stdlib.h>
I have a struct:
struct student {
int age;
int numOfClasses;
int gender; //0 male; 1 female
} student;
When I want to make 7 of those structs using malloc, I will use this line of code:
student stud* = (structure*) malloc(7*sizeof(student));
This line works. That line of code takes the size of the structure and multiples that by 7. In short, this will grab enough memory to make an array of 7 structures.
Now, if I want to change that to 8, I would do this where A is the previous malloced memory, and B is the new malloced (or realloced) memory:
Here is how I have it in code:
stud = (student*)realloc(stud, 8*sizeof(student));
From what I know, realloc takes the variable in the second parameter and mallocs that amount of memory. Then, it takes the pointer (or previous malloced), and fills in the just malloced memory with as much as it can from the given pointer. Of course, the second parameter must be bigger than the previous malloced size, or stud will lose some memory on the end. Now this is where my problem is. When I call the line above, it doesn't change anything. The malloced array is still length of 7. I'm pretty sure, also, that I have enough memory to realloc.
Am I doing this right? Where could my problem be?
Your understanding of realloc's behaviour is nearly correct. It doesn't have to return a different pointer; it may be that there was enough unused memory after the initial block, so the heap manager can just return the same pointer back to you (but adjust its own internal state such that it knows the block is now bigger).
You have made one small mistake, though.
stud = (student*)realloc(stud, 8*sizeof(student));
Here you are replacing your stud pointer with the return value from realloc. If it happens to return NULL due to memory starvation, then you have lost your original stud pointer and the memory is leaked. You should use a temporary pointer instead.
tmp = realloc(stud, 8*sizeof(student));
if (tmp)
stud = tmp;
Also note that you still have to actually put something in the eighth slot. After the realloc the eighth slot is valid allocated memory, but contains garbage until you store something meaningful in it.
This should work, although I'd have these recommendations:
Don't cast the return from malloc. It's useless in C and may hide that you have forgotten to include <stdlib.h>.
Do not use ptr = realloc (ptr, ...) as this creates a memory leak in the case realloc returns NULL. Instead, use
if ((new_ptr = realloc (stud, 8 * sizeof (*stud))) != NULL) {
stud = new_ptr;
} else {
scream_and_die("out of memory");
}
And use sizeof (*stud), i.e. reference an expression using the pointer, not the type being pointed to (to be independent of the particular type of pointer you allocate). This way, when you rename the typedef, the malloc/realloc line needs no modification. In other words, Best Practice for Dynamic Memory Allocation in C is
#include <stdlib.h>
sometype *ptr;
...
ptr = malloc (N * sizeof *ptr);
for an array of N sometypes.
Consider following C code -
typedef struct node
{
int data;
}node;
int main()
{
node *temp;
temp->data=100;
printf("%d",temp->data);
return 0;
}
It gives Segmentation fault on line containing temp->data=100; because (I think) I haven't allocate memory for it. So, there is nothing such as temp->data.But, when I try with -
int main()
{
node *temp,*n;
n=(node*)malloc(sizeof(node));
n->data=100;
temp->data=n->data;
printf("%d",temp->data);
retrun 0;
}
It gives proper output 100.
I haven't allocate memory where temp will point. But still I am copying n->data to temp->data. How ??
The temp pointer takes some garbage value as its not initialised. By chance temp has a garbage value which may happen to be legal address for your program so it runs. If garbage value has illegal adress it will generate segment fault.
You're lucky.
Local variables are not initialized automatically, so when the program begins, both temp and n contain whatever values happen to be on the stack. Next, memory is allocated and n is set to point to it. The value 100 is stored in the data member of the structure.
But temp is still uninitialized, so the value 100 is copied into an unspecified area of memory. Depending on where that memory happens to be, the program may segfault, or it may simply corrupt memory that it doesn't own.
That you haven't got a segfault in temp->data=n->data; is just coincidence. temp is not initialized and hence it points into the digital nirvana.
When you've called malloc you've allocated sizeof node bytes (in reality it may be even a little more) and then you have full memory access to the block pointed to by n.
In general you should call malloc in this way:
node *n;
n = malloc(sizeof *n);
without a cast
with sizeof *n instead of sizeof <datatype>. If you change the datatype (for example you have a typo and instead of typedef .... node you've writen typedef ... nhode. Then you only have to change the declarations of the variables and the rest of the code doesn't have to be changed at all.
Your first code is also right just "temp" is pointing to a garbage value so you have to initialized that.
temp=(node *)malloc(sizeof(node));
Your right on the first part, it segfaults because node* temp isn't pointing anywhere (well, somewhere, but not to allocated memory).
I don't know why the second one "works". I suspect it only appears to work, in that it's not crashing. But since temp was never initialized, who know where it's sticking that '100'. Maybe just hanging around to crash later. Either way, writing to unitialized memory isn't a good idea ;-0
Here's a simplified version of a function I wrote just now:
int foobar(char * foo) {
puts(type);
struct node * ptr = (struct node *) malloc (sizeof(struct node));
puts(type);
memset(ptr, 0, sizeof(ptr));
ptr=head;
return head->id;
}
Here node is just a struct declared as a node in the linklist, which contains a char * and a pointer to the next node. However, I realize that the malloc() here is corrupting my input char * foo.
Why would malloc() corrupt my input char pointer? Also, how could I resolve the issue here? Now I am just copying the content of that pointer to a local array, but this is too hacky, even for my taste (which isn't the best).
Thanks for any inputs!
EDIT: Well, here's more real code:
void foobar(char * type) {
puts(type); <-- here it's a long string about 30 char
struct node * ptr = (struct node *) malloc (sizeof(struct node));
puts(type); <- chopped of, 10 left with some random thing at the end
}
Hope the problem is clear now! Thanks!
EDIT:
Here's how type got initialized:
type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);
Thanks!
The apparent corruption would happen because type or foo points at already freed memory which malloc() gives back to you for a different use.
Once you've released the memory, you cannot continue to use it.
You also have a problem because you allocate to ptr, then wipe ptr out with:
ptr = head;
You might have meant:
head = ptr;
but you would probably need to set ptr->next = head; before that. Of course, this is speculation since you've not shown the type definitions.
It also isn't obvious why you return head->id instead of either head or ptr. Unfortunately, we don't have enough information to say "that is wrong"; it is just not usual.
Commentary on 2nd Edit
Here's how type got initialized:
type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);
There is some of the trouble. You've gone trampling on memory that you have no business trampling on.
The first two lines are fine; you duplicate a string. Note, though, that type is a pointer to 6 bytes of memory, and tempType is a pointer to 7 bytes of memory.
The disaster strikes in the third line.
type + strlen(type) is pointing to the null byte at the end of the type string. You then write 1 byte of tempType over it more or less legitimately; you don't have a null terminated string any more, but the first byte is within bounds. The second and subsequent bytes are written in space that is not allocated to you, and that probably contains control information about memory allocation.
Writing out of the bounds of the allocated memory leads to 'undefined behaviour'. Anything can happen. On some machines, particularly with a 64-bit compilation, you might get away with it altogether. On most machines, and especially 32-bit compilations, you've wrecked your heap memory and something somewhere (typically somewhat distant from this spot) will run into trouble because of it. That is the nature of memory abuse; the place where it occurs often appears to work and it is some other innocent piece of code that suffers from the problems caused elsewhere.
So, if you want to concatenate those strings, you need to do something like:
char *type = strdup("Some ");
char *tempType = strdup("things");
char *concat = malloc(strlen(type) + strlen(tempType) + 1);
sprintf(concat, "%s%s", type, tempType);
I've omitted error checking. You should check the allocations from strdup() and malloc() to ensure that you got memory allocated. Some might argue that you should use snprintf(); it was a conscious decision not to do so since I've calculated the necessary space in the previous line and allocated sufficient space. But you should at least consider it. If you have not ensured that there is enough space available, then you should use snprintf() to avoid buffer overflows. You would also check its return value so you know whether the information was all formatted or not. (Also note that you have 3 pointers to free, or pass off to some other code so that the allocated memory is freed at an appropriate time.)
Note that on Windows, snprintf() (or _snprintf()) does not behave the way specified by the C99 standard. Frankly, that's not helpful.
I'm not sure what you're trying to do, but the comments indicate what's happening:
// This allocates enough memory for a struct node and assigns it to ptr.
struct node * ptr = (struct node *) malloc (sizeof(struct node));
// This displays the data in the (unspecified) string type,
// which must be null terminated.
puts(type);
// This sets the first 4 bytes of ptr to 0, assuming pointers are 4 bytes.
// You probably want memset(ptr, 0, sizeof(struct node));
memset(ptr, 0, sizeof(ptr));
// This makes ptr point to the address of head, orphaning the memory
// that was just malloc'ed to ptr.
ptr=head;