Is malloc-ing a char the same as referencing a char array? - c

I think I have got my head mostly around the difference, but if I am correct, then this should be correct also:
1.)
char *string1 = (char*) malloc(runtime_determined_number);
2.)
char string2val[runtime_determined_number];
char *string2 = &string2val;
Here I would expect string1 and string2 to be the same, is this the case?

string1 and string2 are not pointed to the same memory area
string1 is a pointer pointing to a char array allocated dynamically with malloc
string2 is a pointer pointing to a char array allocated statically

They both point to uninitialized blocks of memory of the same length. So in that respect they are the same, yes.
Note that in case 1, you are responsible for freeing the memory once you're finished. And in case 2, you can't safely return the pointer from a function as the memory will go out of scope on exit.

Using malloc you are asking the OS for memory during runtime. If malloc succeeded you are able to work with the allocated memory. You must deallocate this memory later on!
In your second part you are creating a char-array and then assign its address to a pointer. In this case the memory is taken from the stack and will be freed automatically when the array goes out of scope.
Your char*s won't be the same as they will be pointing to different locations in memory. There is aminor chance they contain the same garbage as you have not initialized them...

They are similar in that they have the same type and have at least runtime_determined_number bytes allocated for them.
They are different in that:
the first version requires an explicit free() to avoid a memory leak;
the lifetime of the two objects may or may not be the same.
Note that the second version is only valid in C99, since it makes use of a variable-length array.

Related

Invalid (Aborted)core dumped error while using free() in C

here's the code:
can anyone explain this issue
how can i deallocate the memory of s in main
char *get(int N)
{
char *s=malloc(10*sizeof(char));
s="hello";
return s;
}
int main()
{
char *s=get(4);
printf(s);
free(s);
}
This here:
s="hello";
Doesn't write "hello" to the allocated memory. Instead, it reassigns s to point to a read-only place where "hello" is stored. The memory you allocated with malloc is leaked, and the free(s); is invalid, because you can't free that read-only memory.
If you want to copy "hello" into s, try strcpy(s,"hello"); instead.
By doing
s="hello";
you're overwriting the returned pointer by malloc() with the pointer to the first element of the string literal "hello", which is not allocated dynamically.
Next, you are passing that pointer (to a string literal) to free(), which causes the undefined behavior.
You may want to change the assignment to
strcpy(s, "hello");
Additionally, by overwriting the originally returned pointer by malloc(), you don't have a chance to deallocate the memory - so you also cause memory leak.
You have two bugs here:
You reassign the pointer s with the reference of the string literal "hello", loosing the memory allocated by malloc
You allocate not enough space for the "hello" string. You need at least 6 characters (not 4)
A variable of type char * is a pointer (memory address) to a character. In C, it is customary to implement strings as zero-terminated character arrays and to handle strings by using variables of type char * to the first element of such an array.
That way, variables of type char * do not actually contain the strings, they merely point to them.
For this reason, the line
s="hello";
does not actually copy the contents of the string, but rather only the pointer (i.e. the memory address) of the string.
If you want to copy the actual contents of the string, you must use the function strcpy instead.
By overwriting the pointer that you use to store the address of the memory allocated by malloc, you are instead passing the address of the string literal "hello" to free. This should not be done. You must instead only pass memory addresses to free that you received from malloc.

Confused about when exactly I should malloc

I know if I am inputting a string into a pointer variable I would malloc that based on the size of the input received.
But what if I am using a pointer variable for the use in strchr? For example if I want the pointer to point to the the character "z" in a string.
char *pointer;
pointer=strchr(string,'z');
Would I need to malloc pointer? Or is it not needed?
You don't have to allocate any memory here . Strchr function returns a pointer to the first occurence of a char in a string if it exists. If a given string deos not contain a char then a null will be returned.
You need to allocate memory only if you want to create something new, that has not been created yet. In this case the input string exists and a pointer will point to a position within this string.
strchr returns a pointer to the first occurrence of character in the C string.
It's pointing to a memory location which is having the character searching in the C string, so no need to allocate new memory using malloc
Using malloc() to allocate space for a pointer and then reassigning the pointer is wrong. You can't even perform pointer arithmetic on it because then you can't free it. You allocate memory and then use that memory, the pointer will then contain the address to that memory, if you overwrite that address then your program will not have a possible way to access that memory not even to free it. Then the allocated memory is useless and there is no point in allocating memory for this.
You must use malloc if you need the system to provide you memory to store data. For example, if you want to store a string you should allocate memory for it
char* s = malloc(10);
strcpy(s, "something");
If you only need a pointer that points to something that already is in memory you mustn't allocate it, in your case the strchr function return a pointer that points to the position in memory where is the char c in the string s
char* c;
c = strchr(s, 'm');

What does "pointer being freed was not allocated" mean exactly?

I have trouble with a program where im trying to copy a string to a structs string variable in c. After copying the string im trying to free the temporary string variable which is copied to the structs string variable. But when i try to free the string the program turns on me and says that "pointer being freed was not allocated". I don't understand exactly what is going on.
char str[]=" "; //temporary string to copy to structs string
str[3]=s; //putting a char s in middle
strcpy(matrix[i-1][j].c, str); //copying the string
free(str); //freeing str that now is useless when copied
Only pointers returned by calls to malloc(), realloc() or calloc() can be passed to free() (dynamically allocated memory on the heap). From section 7.20.3.2 The free function of C99 standard:
The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if
the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc,
the behavior is undefined.
In the posted code, str is not dynamically allocated but is allocated on the stack and is automatically released when it goes out of scope and does not need to be free()d.
Be careful. This code shows confusion about two things:
The difference between stack and heap memory
The operation of strcpy
Point 1
This has already been answered in a way, but I'll expand a little:
The heap is where dynamic memory is given to your process. When you call malloc (and related functions), memory is returned on the heap. You must free this memory when you are done with it.
The stack is part of your process's running state. It is where ordinary variables are stored. When you call a function, its variables are pushed onto the stack and popped back off automatically when the function exits. Your str variable is an example of something that is on the stack.
Point 2
I'd like to know what that c member of your matrix array is. If it is a pointer, then you might be confused about what strcpy does. The function only copies bytes of a string from one part of memory to another. So the memory has to be available.
If c is a char array (with sufficient number of elements to hold the string), this is okay. But if c is a pointer, you must have allocated memory for it already if you want to use strcpy. There is an alternative function strdup which allocates enough memory for a string, copies it, and returns a pointer. You are responsible for freeing that pointer when you no longer need it.
It used free without using malloc. You can't release memory that hasn't been allocated.
Your code doesn't allocate any memory for the string. It simply copies a string from one string to the memory used by another (a string of spaces).
Memory is allocated using functions like malloc(), realloc(), etc. and then freed with free(). Since this memory was not allocated that way, passing the address to free() results in the error.
You did not use malloc() to allocate space in the heap for str. Therefore, str is allocated on the stack and cannot be deallocated with free(), but will be deallocated when str goes out of scope, i.e. after the function containing the declaration returns.

Where are character arrays in dynamically allocated structs stored? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C Array Instantiation - Stack or Heap Allocation?
When dynamically allocating a struct containing a char pointer, what happens with the actual char pointer? Where is it stored?
And once the struct is freed, is the char pointer freed along with it?
For example consider the following struct:
struct mix
{
int a;
float b;
char *s;
};
typedef struct mix mix;
And then the following code that allocates memory for it:
int main()
{
mix *ptr = (mix*)malloc(sizeof(mix));
ptr->a = 3;
ptr->b = 4.5f;
ptr->s = "Hi, there, I'm just a really long string.";
free(ptr);
return 0;
}
Is *s allocated on the stack and then freed along with *ptr? I can imagine it is indeed allocated on the stack as it's not in any way dynamically allocated (unless malloc has some functionality I'm not aware of). And I guess 'going out of scope' for *s would be at the point of freeing *ptr. Or have I got it completely wrong? :)
Thanks very much!
The space for the char* member named s is allocated on the heap, along with the rest of the members of mix after the call to malloc() (whose return value you do not need to cast). The string literal to which s is assigned is not allocated on the heap or the stack, but is part of the actual binary and has static storage duration. So this:
ptr->s = "Hi, there, I'm just a really long string.";
assigns the address of the string literal to ptr->s. If you want ptr->s to point to something other than a string literal then you need to malloc() memory for it. And for every malloc() there must be a free() so ptr->s would need to be free()d before ptr is (if ptr->s is pointing to dynamically allocate memory only).
After the call to free(), dereferencing ptr is undefined behaviour.
When you dynamically allocate mix with malloc(), you are actually allocating a block of memory to store mix structure data members, i.e.
an int (a)
a float (b)
a pointer to a char (s)
And when you call free(), you just release that block.
So, you don't allocate the string, you just allocate the string pointer.
If you want to dynamically allocate the string, you must do it explicitly (with another call to malloc()), and to avoid memory leaks you should also free the string explicitly, using free().
When you malloc for ptr, memory is allocated for all members of the struct including the pointer s which is no different to memory allocated for any other member of the struct.
You are assigning a string literal to s, so it's fine which is usually stored in the read-only section. Otherwise, you'll need to malloc for the ptr->s as well and free. Since, it's a string literal, there's no need to free s here (doing so is UB).
mix* ptr is allocated on the stack. The contents that ptr point at, a variable of type mix, is allocated dynamically on the heap, including the pointer s.
Please note that s doesn't point at anything, the pointer doesn't do anything useful. You have to set it to point at something, which could be allocated anywhere. Whatever it points to is not freed when your struct is freed. In this case you set it to point at a constant string literal allocated in ROM, so you won't need to worry about that.
Is *s allocated on the stack
*s (that is, the result of dereferencing the pointer s) isn't allocated at all. Following the malloc, ptr->s is an uninitialized pointer. It doesn't point to anything, and the expression *(ptr->s) has undefined behavior until you do ptr->s = "Hi, etc".
Once you've initialized ptr->s to point to the string literal, *(ptr->s) is the first character of the string literal, so it probably exists in some data section of the executable. Nothing is dynamically allocated other than the sizeof(mix) bytes for the struct (probably 12 bytes on a 32bit implementation).
what happens with the actual char pointer? Where is it stored?
char* is also like other members, take some bytes(take 8 byte in 64 bit machine, similar to other pointer). In your case, you are allocating memory for that structure instance in heap. so the memory for this pointer also will be allocated in same heap block which is allocated for that structure instance.
Consider this code. This gives where the char* will be:
#include <stdio.h>
typedef struct
{
int a;
float b;
char *s;
}mix;
int main()
{
printf("\n%d ,float:%d, int:%d, char*:%d", sizeof(mix), sizeof(float), sizeof(int), sizeof(char*));
return 0;
}
so size of this structure is 16 bytes. consist of 4 byte integer, 4 byte float and 8 byte char*. (In 64 bit OS, char* will be 4 bytes if OS is 32 bit.)
And once the struct is freed, is the char pointer freed along with it?
Usually the block which is pointed by char* will not be freed(If it points to a block allocated by malloc()). only the structure block will be freed. we know free() needs valid address which is returned during allocation for peaceful de-allocation. If you free without freeing that char*, it will leads to memory leak.
But your case "Hi, there, I'm just a really long string.";
the above given string is string literal which is allocated in read-only section of your program.
use gcc -S Yourprogram.c
This will generate .s file. You can look at .read_only section for this string. so even you delete your structure instance, there will be no memory leak. Because you are just pointing a address which is read-only. You are not at-all allocating memory for this string.

Memory allocated in char * var; declaration

In C, declaring a char pointer like this
char* p="Hello";
allocates some memory for a string literal Hello\0. When I do this afterwards
p="FTW";
what happens to the memory allocated to Hello\0? Is the address p points to changed?
There is no dynamic memory allocation in either statement.
Those strings are stored in your executable, loaded in a (likely read-only) section of memory that will live as long as your process does.
The second assignment only changes what p points to. Nothing else happens.
The memory remains occupied by "Hello". It is lost (unless you have other references to it).
The address p is pointing to (the value of p) is changed of course.
In this case, "Hello" is created at compile time and is part of the binary. In most situation "Hello" is stored in read only memory. "FTW" is also part of the binary. Second assignment will only change the pointer.
in addition - "Hello" and "FTW" have static storge duration as Met have pointed out
It creates a string constant that cannot be modified and should be used as it is.
If you try doing
p[0]='m';
It would give segmentation fault since this is not string literal with allocated memory in which you can reassign and read back values.
what if
p = getbuffer();
getbuffer()
{
return buf = malloc(buf, size);
}
how can free this memory before allocating new memory to p! imagine that p should use getbuffer() many times.

Resources