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

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.

Related

local variable gives "stack smashing detected error" but global variable doesnt [duplicate]

This question already has answers here:
Stack smashing detected
(10 answers)
Closed 7 months ago.
int main(){
char x[] = "123";
srand(time(NULL));
scanf("%s", x);
printf("%s\n", x);
// run();
return 0;
}
But when I make x a global variable it works just fine. Is there any reason behind this?
If you're entering in more than 3 characters, you're writing past the end of the array. Doing so triggers undefined behavior.
With undefined behavior, there are no guarantees regarding what your program will do. It may crash, it may output strange results, or it may appear to work properly.
As for what's happening in practice, local variables reside on the stack. So if you write past the bounds of a stack variable, you could end up overwriting the function's return pointer to its caller or over special sentinel values that are designed to detect such a case.
Global variables on the other hand reside in a data section, not the stack, so it's unlikely that stack objects could be overwritten. It's still possible to overwrite other objects however.

Segmation fault when sending a string as a paremeter [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
I am trying to write a program that converts a string to morse code. It currently works fine whenever input is a string literal but whenever I send a string as a variable I get a segmentation fault.
void morseCode(char* s)
{
for (int i = 0; s[i]!='\0'; i++)
printf("%s",morseEncode(s[i])); //morseEncode is a function which returns char* of morse code
}
int main()
{
int length = strlen("Hello");
char* s = (char*) malloc(length + 1);
s = "Hello";
morseCode(s); // Segmentation fault
morseCode("Hello"); // works fine
return 0;
}
This is a result of passing the variable s to morseEncode (which presumably modifies it) as modifying s is undefined behaviour. Specifically, modifying a string literal in such a manner is undefined behaviour per 6.4.5p6 [from C99:TC3]
It is unspecified whether these (string literal) arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
(text in parentheses added by me)
You might also want to take a look at this question.
You could instead declare s like so (with automatic storage duration).
char s[] = "Hello";
If you need s to be a pointer you could try
// Yes, sizeof(char) will always be 1 and you could remove it.
char *s = malloc(sizeof(char) * (strlen("Hello") + 1));
strcpy(s, "Hello");
// Your code that uses s here
free(s) // Important!
As an additional note #kaylum has pointed out that the original answer didn't provide a justification as to why calling the function in the two different ways produced different results. This is because the undefined behaviour you're running into just so happened to be undefined in a different way for each call. If I write out a similar program and compile it using gcc (with no flags) I end up running into a segfault both ways; on the other hand, compiling with clang -O both work! Its simply a product of whatever segment(s) of memory your specific compiler has decided you place each of those sequences of characters.

Why am I able to copy more bytes than defined in the char array? [duplicate]

This question already has answers here:
Why doesn't my program crash when I write past the end of an array?
(9 answers)
Closed 3 years ago.
I have the following code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buffer[2];
strcpy(buffer, "12345678910");
printf("%s\n", buffer);
return 0;
}
Since, I have already defined the char array with size 2, I shouldn't be able to put in more than 2 char plus null terminating character. Yet, it is able to take more than that without any buffer overflows or segmentation faults. Even if I copy the string strcpy(buffer, "123456789101298362936129736129369182");, it works fine. The error is generated when I push strcpy(buffer, "1234567891012983629361297361293691823691823869182632918263918");.
More of a theroetical question than a practical, but I hope it helps the new and the experienced programmers alike since it talks about the fundamentals, and helps improving coding ethics. Thanks in advance.
The simple answer is that C does not protect you from yourself. It's YOUR responsibility to check boundaries. The program will happily read and write wherever you instruct it to. However, the operating system may say something if you do this, which is usually a "segmentation fault". A worse scenario is that it may overwrite other variables.
This is a source of many bugs in C, so be careful. Whenever you're writing outside outside a buffer, you're invoking undefined behavior and these can manifest themselves in various ways, including the program working as it should, overwriting variables and segmentation faults.
I shouldn't be able to put in more than 2 char plus null terminating character
This is a common bug. It's NOT "plus null terminating character". It's INCLUDING null terminating character.

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.

segmentation fault in after return? [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
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.

Resources