C Segmentation Fault when trying strcpy on char *pointer [duplicate] - c

This question already has answers here:
C segmentation fault-char pointers
(3 answers)
Closed 8 years ago.
I'm new in learning the C-Language and I have a question to pointers.
For Example if I try this:
char *pointer;
strcpy(pointer,"Hello, World!\n");
printf(pointer);
I get this Output:
Segmentation Fault
But if I try this:
char *pointer = "Hello, World!\n");
printf(pointer);
I get this:
Hello, World!
My question is why it isn't working with strcpy.
The functions do the same overall.
What is the difference between the first sourcecode and the second?
It would be good if someone could explain what is happening in the memory, so that I can get a better view at this.

char* pointer merely gives you a variable to use to access the memory location. You've not yet allocated any memory, so when you do the strcpy you're writing to whatever random/undefined value pointer has.
You need to do something like:
char* pointer = calloc(LEN);
if (pointer)
{
strcpy(pointer, "Hello World");
printf(pointer);
free(pointer);
}

The first parameter to "strcpy" should be pointing to a usable location in memory. In your first source code, you havent initialized "pointer" to anything. You should first initialize it, for example by declaring it to be an array of characters of maximum length:
char myArray[42]; // where 42 represents the maximum capacity

Related

Why does malloc seemingly allow me to write over memory? [duplicate]

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);

Why this code compile but not running [duplicate]

This question already has answers here:
What is the trick behind strcpy()/uninitialized char pointer this code?
(3 answers)
Closed 5 years ago.
Why this code compile but not running?
int main() {
char *s;
scanf("%15s", s);
puts(s);
}
Because s is an uninitialized pointer, you cannot store data there (since there "is no there there").
Try:
char s[32];
instead, that gives you 32 characters' worth of room into which scanf() can write.
You need to provide memory for scanf(...) The char *s is only a pointer to some memory, but not he memory itself. You can either malloc(...) the memory and have s point to it, or allocate it locally on the stack by char s[16]
For starters, provide a proper buffer to the scanf call. For example, instead of char *s which is simply an uninitialized pointer, try char s[128].

Unable to predict the ouput of the following program [duplicate]

This question already has answers here:
Returning an array using C
(8 answers)
Closed 8 years ago.
I have an idea on dangling pointer. I know that the following program will produce a dangling pointer.But I couldnt understand the output of the program
char *getString()
{
char str[] = "Stack Overflow ";
return str;
}
int main()
{
char *s=getString();
printf("%c\n",s[1]);
printf("%s",s); // Statement -1
printf("%s\n",s); // Statement -2
return 0;
}
The output of the following program is
t
if only Statement-1 is there then output is some grabage values
if only Statement-2 is there then output is new line
Your code shows undefined behaviour, as you're returning the address of a local variable.
There is no existence of str once the getString() function has finished execution and returned.
As for the question,
if only Statement-1 is there then output is some grabage values if only Statement-2 is there then output is new line
No explanations. Once your program exhibits undefined behaviour, the output cannot be predicted, that's all. [who knows, it might print your cell phone number, too, or a daemon may fly out of my nose]
For simple logical part, adding a \n in printf() will cause the output buffer to be flushed to the output immediately. [Hint: stdout is line buffered.]
Solution:
You can do your job either of the two ways stated below
Take a pointer, allocate memory dynamically inside getString() and return the pointer. (I'd recommend this). Also, free() it later in main() once you're done.
make the char str[] static so that the scope is not limited to the lifetime of the function. (not so good, but still will do the job)
your str in getString is a local variable, which is allocate on stack, and when the function returns, it doesn't exist anymore.
I suggest you rewrite getString() like this
char *getString()
{
char str[] = "Stack Overflow ";
char *tmp = (char*)malloc(sizeof(char)*strlen(str));
memcpy(tmp, str, strlen(str));
return tmp;
}
and you need to add
free(s);
before return 0;
In my case, pointer tmp points to a block memory on heap, which will exist till your program ends
you need to know more about stack and heap
Besides, there is still another way, use static variable instead
char *getString()
{
static char str[] = "Stack Overflow ";
return str;
}
PS: You get the correct answer for the following statement printf("%c\n",s[1]); is just a coincidence. Opera System didn't have time to do some clean work when you return from function. But it will
Array is returned as a pointer yet the array itself is the garbage after return from function. Just use static modifier.
What's concerning s[1] is OK. The point is, it's the first printf after getting the dangling pointer. So, the stack at this point is still (probably) intact. You should recall that stack is used for function calls and local variables only (in DOS it could be used by system interrupts, but now it's not the case). So, before the first printf (when s[1] is calc'ed), s[] is OK, but after - it's not (printf' code had messed it up). I hope, now it's clear.

memcpy() function usage in C [duplicate]

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.

Memory allocation for pointers [duplicate]

This question already has answers here:
Where does the compound/string literals get stored in the memory?
(4 answers)
Closed 9 years ago.
I have a following program:
#include<stdio.h>
char * test()
{
char * rt="hello";
return rt;
}
void main()
{
printf("\n %s \n", test());
}
here, it correctly prints hello while if rt is not a constant pointer like char rt[]="hello" it prints garbage. My understanding, in latter stack gets freed when function returns from test but what happens with above case? where does the memory for char *rt is allocated?
Extending above part, If I try to do char rt[]="hello" and if i try rt="hrer" it throws error while with char *rt="hello" it works fine but we can not change particular character in a string with later case. Please help me to understand it. Thanks.
Your string "hello" is what is called a string literal. It resides in what is called the data segment of your program, which is a region of memory. Any other string literals throughout your code are put there as well. This region is loaded once, and never destroyed.
So, your pointer rt is pointing somewhere into that region.
But, if you declare char rt[] = "hello", you are declaring an array named rt[] on the stack and the array is 6 bytes long (hello + null terminator). When the function returns, the stack is freed, so, this memory will be invalid.
Some more information on string literals are here: C String literals: Where do they go?
The string Hello gets set into the read portion of the executable part of the program. The function returns a pointer to that.
The use of an array (in the second case) means that it gets copied onto the stack.
End of the function it gets zapped - hence garbage

Resources