segmentation fault in after return? [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am getting Segmentation fault after return executes. Why is it coming after return and not in strcpy?
int main()
{
char a[2];
strcpy(a,"0123456789101112131415161718192021222324252627282930");
printf("%s\n",a);
return 0;
}

I am getting Segmentation fault after return executes. Why is it coming after return and not in strcpy?
You have made a common mistake called a buffer overflow. This results in undefined behavior, which is a standards answer. However, if you understand how a typical machine uses a stack, you can understand why it crashes when you return. Most CPUs use a down ward growing stack. So before you call strcpy, the stack is something like,
sp + 0 : a[0]
sp + 1 : a[1]
sp + 2 : padding
sp + 3 : padding
sp + 4: return address (four bytes)
The compiler machinery creates a call frame each time you use a function in 'C'. The return address exists as part of stack where the compiler allocates space for your a[] array. As it is under-sized for the string copy, you over-write the return address. This value isn't used until you return. The return address will be overwritten with something like the value 0x34353637 which is the binary pointer for the ASCII text '4567'.
It is advisable to use something like strncpy or an alternative. For example,
strncpy(a,"012345678...", sizeof(a));
a[sizeof(a)-1] = 0; /* ensure the string is terminated. */
Obviously you need to increase the size of your 'a' array if you want the full string to be printed.

Why is it coming after return and not in strcpy?
You get the segmentation fault when main returns because you overwrite critical data (saved frame pointer and return address) in the stack frame of main function and not in the stack frame of strcpy function.
As others already said, you invoke undefined behavior and anything can happen: from nothing to a nuclear war.

You're trying to load a string with a lot more than 2 characters into a char array that only holds 2 characters. This will cause a segmentation fault, since you are overwriting the memory allocated for the char array, which can also cause undefined behavior.

Your program overwrote the buffer, that would cause undefined behavior, which means literally anything could happen.

Related

Why is this having trouble storing illegal the character? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
It's an exercise of my college. The goal is to make illegal memory store and illegal memory access and print it in char. However, using MALLOC has memory adresses doesn't store 'y', and using char x works. Why this difference? But when I use char x it shows me what I want, however, in the end show me this text "* stack smashing detected *: terminated
Abortado (imagem do nĂșcleo gravada)"
void ilegal_store(char *u)
{
for(int i=0;i<100;i++){
*(u+i) = 'y';
}
}
void ilegal_reading(char *u)
{
for(int i=0;i<100;i++){
printf("%d = %d\n",i,*(u+i));
}
}
void main()
{
//char x; WORKS
char *x=(char *)malloc(sizeof(char)); //USING MALLOC HAS ADRESSES WHICH DOESN'T STORE THE 'y' by ilegal_store();
if(x!=NULL){
ilegal_store(x); //use &x when not pointer
ilegal_reading(x); //use &x when not pointer
}
}
The C standard does not permit you to dereference a pointer to memory that you don't own. The behaviour on attempting to do so is undefined. Undefined behaviour manifests itself in many curiosities such as "working" sometimes, not "working" sometimes, or the compiler even erasing that particular branch: it's allowed to assume that undefined behaviour does not occur.
It's possible that you will not get a crash at exactly the first undefined dereference. Because the output of printf is frequently buffered and therefore often in lag of the code generating the output, you might be able to produce a extra output for the uncommented case by flushing the buffer after every iteration using fflush(stdout). The presence of the newline character in the case you cite as working can also flush the buffer. It's probably the newline character that is producing the different behaviour.
Finally, however this is dressed up, you are circumventing contraints the language places on you. If you want to circumvent these constraints then you need to use a different language. Many C compilers support inline assembly. That's what you need to use in this instance.

Why do I have a undeclared variable existed? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am writing a function in C. What I found is that when I debug in gdb, I found a pointer "result" has the same address with another pointer before "result" was declared. Part of my code:
char* stringSum(char* x, char* y){
puts(x);
puts(y);
printf("\n");
int lengthx=strlen(x);
int lengthy=strlen(y);
int lengths=MIN(lengthx,lengthy);
int lengthl=MAX(lengthx,lengthy);
char* s=((lengthx<=lengthy)?x:y);
char* l=((lengthx>lengthy)?x:y);
int returnSize=MAX(lengthx, lengthy)+2;//-----I could print result now
printf("before, short is : ");puts(s);
char* result=malloc(sizeof(char)*returnSize);//-----but result is allocated now
printf("after allocate memory for result, short is: ");puts(s);//---s is changed!
result[returnSize-1]='\0';
......
}
This function get the sum of two numbers (in string) so that I could calculate the sum of two large numbers. In gdb: I got this weird problem:
My problems are in red and yellow rectangles
(When debug in gdb) Before char* result=malloc(sizeof(char)*returnSize); I print s and result (so now it haven't been declared yet) and got
(gdb) print s
$5 = 0x61f950 "6597242170048699800240000000000"
(gdb) print result
$6 = 0x61f950 "6597242170048699800240000000000"
I couldn't understand that since how could an undeclared pointer points to an existing address? (This function is called by another function with a very large number of x and y (in string). If I changed them to relatively small values I will always get the right answer. What's more, if I create a new .c file and only have this function and main function, I will not have that problem anymore even with a large value.)
My second problem is that I have printed s twice and I found the second time I print (after declare the pointer result) s is changed! (Similar to the first problem, if I choose smaller values for x and y or create a new .c file, I will not have the same problem.)
I guess I have some problem with malloc but after search online I haven't find any useful resources will could help me solve the problem. Do I have the problem about memory management?
You have at least two serious problems with your code.
The first problem is that you never free what you malloc, creating sizeable memory leaks at each recursive call.
The second problem is that you are trying to assign strings, which doesn't have the effect you hope for.
Here is an example of what you do (comments mine):
// allocate some memory and assign its address to abcd
char* abcd=malloc(sizeof(char)*returnSize);
// throw it away by assigning a different value to abcd
abcd=karatsuba(stringSum(a,b),stringSum(c,d));
// then assign yet another different value to abcd
abcd=stringSubstract(abcd,ac);
// and another one
abcd=stringSubstract(abcd,bd);//ab+cd
// Code below overflows, because memory abcd is pointing to is
// not the original block allocated for it (you threw it away).
// It is a block allocated and returned by stringSubstract.
// Its length is not necessarily sufficient to accommodate all
// the data you are trying to stuff in it.
int labcd=strlen(abcd);
for(i=0;i<=(ns/2-1);i++){
abcd[labcd+i]='0';
}
abcd[lac+i]='\0';
You can verify that this is the case by running your program under valgrind. You will get error messages that indicate a buffer overflow just before the mysterious shortening of s. It all goes downhill from there.
In order to fix the problem, you may want to use strcpy instead of pointer assignment. Another way to fix it would be ditching the abcd = malloc(...) lines in the beginning of the function, and using realloc to make sure they have the allocations have enough size.
In addition you definitely want to fix the memory leaks. You need to call free for each variable you malloc after you're done with it. If you are returning a malloced variable, the caller needs to free it after using it.

Is strdup adding a '\0' when duplicating the array of char? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
i would like to know if strdup adds a '\0' at the end of the new array if the src array does not contain one ?
let's assume we have an array containing "hello" allocated by this kind of malloc
malloc(sizeof(char) * 5);
so 5 bytes for 5 characters.
I guess the src string did not received the sufficient memory for the '\0'.
What is supposed to happen in this case ?
First the standard disclaimer: strdup isn't a standardized function, so exactly what it does could (at least in theory) vary from one compiler to the next. That said, every implementation I've seen of it has worked the same way.
strdup will determine the length of the input string--it'll start from the address in the pointer you pass, and find the first NUL byte after that location. Then it'll allocate a new block of memory and copy the bytes in that range to the newly allocated block.
So one of two things will happen. Either the input will contain a zero byte, and the result will too, or else strdup will read past the end of the input you passed, and you'll get undefined behavior (but chances are pretty good it'll find a zero byte eventually, and copy a bunch of extra garbage to the duplicate string).
One other minor note: if you use strdup, and then try to port you code to a compiler that doesn't define it, you might consider writing your own:
char *strdup(char const *s) {
size_t len = strlen(s) + 1;
char *ret = malloc(len);
if (ret != NULL)
strcpy(ret, s);
return ret;
}
That's obviously a pretty easy thing to do, but it has one other problem: including it in your code produces undefined behavior. You're not allowed to write a function with a name that starts with str. Those are all reserved for the implementation. So even though the function is simple and the behavior of its content is perfectly well defined, the mere existence of the function as a whole still gives undefined behavior.
What strdup() will do in this case is start with the string passed, and go on looking through memory until it either falls off the end of allocated memory (and you get a SIGSEGV or similar) or finds a byte that happens to contain a '\0'.
It will allocate enough memory to include a copy of everything it scanned, including the '\0', and then copy everything.

How does the program identifiy the end of a array pointed by a pointer and created dynamically? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Would you like to help me to understand the mechanism of "pointers" in C:
How does the program identify the end of an array, which was dynamically allocated and pointed at by a pointer (example: montext1)? Where are these arrays stored in RAM (probably not in data, not in stack, perhaps in the heap)?
A pointer is defined by a type and a size: how is this implemented in RAM for a dynamic allocation like in the example below?
#include <stdio.h>
char * gettext()
{
char *text;
printf("Text:");
scanf("%s", &text);
printf("\n");
return text;
}
int main()
{
char *montext1 = gettext();
char *montext2 = gettext();
}
Your program is very wrong, and has undefined behavior. So it's not a very good starting point for discussion.
There is no "dynamic allocation" in your program, only chaotic overwriting of random memory.
It should use heap allocation, i.e.:
char * gettext(void)
{
char *s;
printf("Text:");
fflush(stdout);
if((s = malloc(256)) != NULL)
{
if(fgets(s, 256, stdin) == NULL)
{
free(s);
s = NULL;
}
}
return s;
}
The caller must free() the returned string, and check for NULL before printing it.
The problem here is the CPU does not know the end of the data pointed to by a pointer. For the CPU it's just raw bytes in the memory which can be either application bytes or data entered by the user. However the compiled C code via the C std library know the string (char*) is supposed to end with a zero byte. That's how it knows where the end is.
But, in the gettext method: you need to allocate some memory too, via malloc (calloc), because in it's current stage your application is writing into memory which is not owned by it. And of course, the caller of gettext needs to free the memory.
And finally: a pointer is just an address in the memory, it points to some bytes. It is the role of the application to interpret those bytes in the proper way, such as identify zero terminated strings.
How does the program identify the end of an array, which was dynamically allocated and pointed at by a pointer
This is handled internally by the dynamic memory allocation library routines and it is handled differently on every implementation. The actual code could be in stdlib or it could be in an OS API. So how it is done depends on compiler and OS both.
Where are these arrays stored in RAM
If they were dynamically allocated, they were stored on the heap.
A pointer is defined by a type and a size
No, a pointer is a type, end of story.
how is this implemented in RAM for a dynamic allocation like in the example below
You linked no example containing dynamic allocation. The code you posted is nonsense code. It attempts to copy data into the address where you allocated a pointer. This doesn't make any sense, so the program will crash and burn.
If you rewrite the program so that scanf("%s", &text); is replaced by scanf("%s", text);, then you attempt to copy data into an uninitialized pointer's address, which is random. This is undefined behavior and will also cause your program to crash and burn.

assignment of string using strcpy and equal operator [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
What is difference between the following code?
1.
char *p;
strcpy(p,"String");
2.
char *p;
p = "String";
The pointer points to the same string, but is there any difference?
In order for the first operation to work, p must point to a writable block of memory at least 7 bytes in size. The second operation does not require it.
After the first operation the string remains writable: you can do this on the first string, but not the second:
*p= 's'; // Make the value all lowercase
The second pointer assignment points p to a memory of a string literal; writing to that memory is undefined behavior.
(1) is a memory scribble and possibly a runtime error.
You cannot copy into memory you don't own (haven't allocated in some way).
In the first point you say you want to copy the string to the memblock p is pointing to
(so you have to make sure, there is enough space where the string can be copied to)
In the second case you just make p pointing to the read only address of "String".
p -> [S][t][r][i][n][g][0]
But you should get compiler warnings as far you don't declare p as p const *

Resources