This question already has answers here:
Segmentation Fault - declare and init array in C
(3 answers)
Closed 8 years ago.
I have a query about using the memcpy() function.I have written the below program, it compiles but doesn't print an output. The .exe opens and the crashes. I am using Code Blocks as my IDE using GNU GCC compiler.
int main()
{
char a[]= "This is my test";
char *b;
memcpy(b,a,strlen(a)+1);
printf("After copy =%s\n",b);
return(0);
}
However, if I change the array *b to b[50] it works!! I don't understand why.
Please provide your suggestions!
Thanks!
Your pointer b is uninitialized. It is pointing to some random location in memory. So when you copy stuff into the memory which b is pointing to, bad things are likely to happen.
You need to initialize it; perhaps allocate some memory for it with malloc().
char *b = malloc(strlen(a) + 1);
And then free it when you're finished.
free(b);
You are lucky it did not crash when you used pointer - it should have.
When you copy memory, destination must be allocated first. If you use char b[50], you allocate 50 bytes for b on stack. If you use char *b, you did not allocate anything yet, and typically should do this using something like malloc : b = malloc(50);.
With malloc it will work, but then you should not forget to release that memory with free(b);.
If memory was allocated on stack, release happens automatically.
Related
This question already has answers here:
Expanding an array with malloc
(4 answers)
In C, are arrays pointers or used as pointers?
(6 answers)
Closed 2 years ago.
I'm trying to reallocate memory using the realloc function, I saw that you need to use malloc before but I don't understand if you MUST use it because let's say I'm creating the following string:
char string[] = "fun";
would the realloc function work if I try to add more space?
that brings me to my question, I'm trying to simply add one letter at the end of the string, lets say 'p', but for some reason the program crushes on the realloc line every time I run it.
Here is my full code:
int main()
{
char string[] = "fun" ;
str_func(string);
printf("%s", string);
return 0;
}
void str_func(char* str)
{
str = (char*)realloc(str, strlen(str) + 2);
strcat(str, "p");
}
I also tried making a pointer to 'string' and sending the pointer, which results the same thing.
would the realloc function work if I try to add more space?
No, because that array is no allocated on the heap - in your case it is very likely allocated on the stack and can't get resized. Simply put: realloc doesn't recognize the pointer and doesn't know what to do with it, but tries to do something anyway, hence the crash.
You can only call realloc on a pointer that was previously passed to malloc, or on a null pointer. That's just how these functions work.
For details, see What gets allocated on the stack and the heap?.
I saw that you need to use malloc before but I don't understand if you MUST use it
If you need to use malloc before you can realloc something, then by definition you must only realloc things originally allocated with malloc.
You're trying to find some space between "need" and "must" that doesn't exist.
... for some reason the program crushes on the realloc
You already said you know you need to use malloc. Then you didn't use malloc, and you're asking why this is a problem. You could at least try doing the thing you "know" you need to do, to see if that solves the problem.
The program should probably look like
int main()
{
/* array is an automatic local variable. It wasn't dynamically allocated
in the first place, so can't be dynamically re-allocated either.
You cannot (and don't need to) free it either, it just goes out of scope
like any other automatic variable.
*/
char array[] = "fun";
/* you need to use malloc (or one of the other dynamic allocation functions)
before you can realloc, as you said yourself */
char *dynamic = malloc(1+strlen(array));
memcpy(dynamic, array, 1+strlen(array));
/* realloc can move your data, so you must use the returned address */
dynamic = str_func(dynamic);
printf("old:'%s', new:'%s'\n", array, dynamic);
/* not really essential since the program is about to exit anyway */
free(dynamic);
}
char* str_func(char* str)
{
char* newstr = realloc(str, strlen(str) + 2);
if (newstr) {
strcat(newstr, "p");
return newstr;
} else {
/* we failed to make str larger, but it is still there and should be freed */
return str;
}
}
Your original condition isn't quite correct: actually the pointer passed to realloc
... must be previously allocated by malloc(), calloc() or realloc() and not yet freed with a call to free or realloc
[OR] If ptr is NULL, the behavior is the same as calling malloc(new_size).
The realloc function only works with things that were originally created with a small group of allocation functions (such as malloc, calloc, or realloc itself), or the null pointer. Since string is none of those things, your code is not well-defined.
This question already has answers here:
How can I correctly assign a new string value?
(4 answers)
Closed 4 years ago.
Why does this not return a segmentation fault 11?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
char *test;
test = (char*) (malloc(sizeof(char)*3));
test = "foo";
printf("%s\n", test);
test = "foobar";
printf("%s\n", test);
return 0;
}
My outcome is
foo
foobar
I'm fairly new to C, but when I was compiling this using both gcc on mac and Windows Debugger on Windows 10, it doesn't crash like I expected.
My understanding is that by using (char*) (malloc(sizeof(char)*3)), I am creating a character array of length 3. Then, when I assign test to the string foobar I am writing to 6 array positions.
I'm left sitting here, staring at my apparently valid, runnable code scratching my head.
test = "foo";
Here you do not copy the string to the allocated memory, test no longer points to the allocated memory, instead it points to the string literal "foo". Same goes for "foobar". Also as pointed out in the comments the address of the allocated memory is lost and therefore it is a memory leak (since there is no way to retrieve the address of the memory).
If you want to copy a string to another destination you need to use strcpy or loop over every character.
If you write or read outside bounds of the allocated space you are invoking undefined behavior. That means that basicly everything can happen, also that it works.
Your program never writes to the location pointed to by the return from malloc(). All you've done with e.g. test = "foo"; is change what test points to, which by the way is a memory leak since you've then lost what malloc() returned.
To properly use the memory you allocated with malloc(), use strcpy(), snprintf(), etc.
Also, don't forget the null terminator in your C strings. To properly store e.g. "foobar" you need at least 7 bytes, not 6.
First thing is that you waste the memory allocated by malloc unnecessorily by storing the address of foo into that.
If you are going to point to string in code section then there is no need to allocate memory to the pointer.
When to allocate memory to pointer
e.g. when you intended to scan 'n' number of bytes from keyboard in pointer.
char *ptr,num_char;
scanf("%d",&num_char);
ptr = (char *)malloc(num_char*sizeof(char));
scanf("%s",ptr);
This question already has answers here:
Why don't I get a segmentation fault when I write beyond the end of an array?
(4 answers)
Closed 7 years ago.
I'm actually learning C and I got a "problem".
I created a pointer to a structure with a char* and int with malloc(1).
The pointer works and I can edit structure children without problems.
I also created a pointer to a int (still with malloc(1)) and it works. Another thing is I didn't get core dump error when I tried to access *(pointer + 33780) (Core dump comes when the value is a bit higher) it worked, but default value was 0.
Thank you, that's not a "problem" but I'd like to know why is that doing like this.
Sorry for being the English's murderer.
EDIT : Here the code
struct Personne
{
char *name;
int age;
};
int main(int argc, char *argv[])
{
printf("%ld\n", sizeof(struct Personne));
struct Personne *testPoint = malloc(1);
printf("testPoint : %p\n", testPoint);
printf("testPoint : %p\n", testPoint->name);
testPoint->name = "UnNomInconnu";
testPoint->age = 20;
free(testPoint);
return 0;
}
Actually function malloc does not allocate a memory extent exactly of the size of 1 byte or of a similar small value. Usually the minimum size of an allocated extent is equal to the size of the paragraph that is to 16 bytes.
So if you will write for example
char *p = malloc( 1 );
then the actual size of the allocated extent can be equal to 16 bytes.
Nevertheles you should not rely on this feature becuase in general that is according to the C Standard this is undefined behaviour.
struct Personne *testPoint = malloc(1);
puts you into the realm of undefined behavior. Unfortunately UB can include "the program runs correctly in all test environments but fails in production at worst possible time" - and frequently does.
If you are on linux run your program under valgrind and/or electric fence. You will see why those tools exist.
You need:
struct Personne *testPoint = malloc(sizeof(*testPoint));
1 byte is not enough memory for your structure. The meaning of malloc() argument is the number of bytes. However, malloc() does not necessarily protect the memory beyond the allocated segment, so in some cases it is possible to overwrite the boundary without fatal consequences.
This question already has answers here:
Why freed struct in C still has data?
(7 answers)
Closed 8 years ago.
int main(int argc, char **argv)
{
counter = 0;
int size = 5;
struct trie *mainTrie = malloc(size * sizeof(mainTrie));
test(mainTrie);
printf("%c", mainTrie[2].alphabet);
free(mainTrie->alphabet);
printf("%c", mainTrie[2].alphabet);
return 0;
}
The test functions was just to see how I can use malloc. My experiment was successful except one thing: free(mainTrie).
When I added printf("%c", mainTrie[2].alphabet) after I 'freed' the memory spaces, the output still gave me the same letter that was stored at mainTrie[2].alphabet from method 'test'.
Am I not understanding something? Thanks in advance...
Show us your complete code, specially the maintree struct. It seems like you need to free the maintree variable:
free(maintree);
However, freeing memory means that the piece of memory you reserved will be available to the O.S again. It doesn't mean you actually set that piece of memory tu NULL. Edit: #MattMcNabb "Typically the memory is not released to the OS, just made available for further allocations from the same process. (This depends on a lot of things of course)"
It is possible that you are printing a piece of memory that doesn't belong to your program anymore, but the data hasn't changed yet.
Note these 2 important things from the documentation
A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations. (just deallocated, doesn't say anything about the values being changed)
If ptr does not point to a block of memory allocated with the above functions, it causes undefined behavior.
If ptr is a null pointer, the function does nothing.
Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location. (so you maybe pointing to a piece of memory you allocated in the past, but it still has the same values, it is possible, it wont happen all the time).
I am just learning C (reading Sam's Teach Yourself C in 24 hours). I've gotten through pointers and memory allocation, but now I'm wondering about them inside a structure.
I wrote the little program below to play around, but I'm not sure if it is OK or not. Compiled on a Linux system with gcc with the -Wall flag compiled with nothing amiss, but I'm not sure that is 100% trustworthy.
Is it ok to change the allocation size of a pointer as I have done below or am I possibly stepping on adjacent memory? I did a little before/after variable in the structure to try to check this, but don't know if that works and if structure elements are stored contiguously in memory (I'm guessing so since a pointer to a structure can be passed to a function and the structure manipulated via the pointer location). Also, how can I access the contents of the pointer location and iterate through it so I can make sure nothing got overwritten if it is contiguous? I guess one thing I'm asking is how can I debug messing with memory this way to know it isn't breaking anything?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct hello {
char *before;
char *message;
char *after;
};
int main (){
struct hello there= {
"Before",
"Hello",
"After",
};
printf("%ld\n", strlen(there.message));
printf("%s\n", there.message);
printf("%d\n", sizeof(there));
there.message = malloc(20 * sizeof(char));
there.message = "Hello, there!";
printf("%ld\n", strlen(there.message));
printf("%s\n", there.message);
printf("%s %s\n", there.before, there.after);
printf("%d\n", sizeof(there));
return 0;
}
I'm thinking something is not right because the size of my there didn't change.kj
Kind regards,
Not really ok, you have a memory leak, you could use valgrind to detect it at runtime (on Linux).
You are coding:
there.message = malloc(20 * sizeof(char));
there.message = "Hello, there!";
The first assignment call malloc(3). First, when calling malloc you should always test if it fails. But indeed it usually succeeds. So better code at least:
there.message = malloc(20 * sizeof(char));
if (!there.message)
{ perror("malloc of 20 failed"); exit (EXIT_FAILURE); }
The second assignment put the address of the constant literal string "Hello, there!" into the same pointer there.message, and you have lost the first value. You probably want to copy that constant string
strncpy (there.message, "Hello, there!", 20*sizeof(char));
(you could use just strcpy(3) but beware of buffer overflows)
You could get a fresh copy (in heap) of some string using strdup(3) (and GNU libc has also asprintf(3) ...)
there.message = strdup("Hello, There");
if (!there.message)
{ perror("strdup failed"); exit (EXIT_FAILURE); };
At last, it is good taste to free at program end the heap memory.
(But the operating system would supress the process space at _exit(2) time.
Read more about C programming, memory management, garbage collection. Perhaps consider using Boehm's conservative GC
A C pointer is just a memory address zone. Applications need to know their size.
PS. manual memory management in C is tricky, even for seasoned veteran programmers.
there.message = "Hello, there!" does not copy the string into the buffer. It sets the pointer to a new (generally static) buffer holding the string "Hello, there!". Thus, the code as written has a memory leak (allocated memory that never gets freed until the program exits).
But, yes, the malloc is fine in its own right. You'd generally use a strncpy, sprintf, or similar function to copy content into the buffer thus allocated.
Is it ok to change the allocation size of a pointer [...] ?
Huh? What do you mean by "changing the allocation size of a pointer"? Currently all your code does is leaking the 20 bytes you malloc()ated by assigning a different address to the pointer.