Arrays Stack Overflow [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
#include
int main(void)
{
char str[100]="88888888888888";
char t[20]="";
gets(t);
puts(str);
puts(t);
return 0;
}
The first line
555555555555555555555555555555555
is put in.
Why str is 55555555555? Why str isn't 88888888888888888 or 55555555555588888?

You overriden the t buffer, and reached the str buffer, where the rest of the input, and the null terminator was set. And puts prints only until the null terminator.
Pretty much looks like that:
[ t (20) ][str(100) ]
55555555555555555555 5555555555555\0
Note that although t is declared as char[20], when you print it you get the full input (longer than 20), since puts stops at the null terminator (again).
BTW, this is a buffer overflow, not a stackoverflow, but stack overflow is possible on this codeas well.

As Binyamin said it is caused by the overflow you trigger because of the input string being too long. However it is a bit random thing - sometimes the two memory allocations will happen just next to each other and the string will extend to the neighbouring variables, sometimes it might not happen.
I advise you to place guard conditions for such kind of overflows.
If you see in the gets documentation:
Notice that gets does not behave exactly as fgets does with stdin as
argument: First, the ending newline character is not included with
gets while with fgets it is. And second, gets does not let you specify
a limit on how many characters are to be read, so you must be careful
with the size of the array pointed by str to avoid buffer overflows.
In your case if you do not know the size apriory maybe it is better idea to use fgets as it is more secure (though a bit slower).

When you enter a string of more than 20 5s, it overruns the buffer that was allocated to t and extends into the buffer that was allocated to str.
Then it displays the contents of str, which is the string you entered, starting at the 21st character.
Finally, it displays the contents of t, but since that string doesn't end with a null character, it continues displaying memory (which is the buffer assiged to str) until it encounters the null character after all the 5s.

In order to avoid those allocation overlapping issues you can try this alternative, so that the allocation takes place at runtime if I'm not wrong:
#include <iostream>
int main(void)
{
char *str;
char *t;
str = new char(100);
str = (char*)"88888888888888";
t = new char(20);
std::cin >> t;
puts(str);
puts(t);
return 0;
}

Related

taking length of predefined string vs getting one from input [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I seem to be unable to understand why do these two cases behave differently:
const char* TEXT = "hello world!";
int length = (int) strlen(TEXT);
char* array[length];
this is ok, however this one:
char* text;
scanf("%[^\n]s", text);
// input "hello world!" and press enter
int length = (int) strlen(text);
char* array[length];
ends with a segmentation fault
what am I missing?
For the scanf call, text parameter, you do not allocate any memory. You also do not initialize the variable to a value. This results in scanf writing to random memory, which causes your segmentation fault.
To fix this issue you need to allocate a buffer of a reasonable size:
char* text = malloc(1024);
1024 is the maximum size that you expect the input data to be. This, however, still leaves the code vulnerable to buffer overflows. To prevent buffer overflows you can inform scanf that text is of a certain size; look for the answers here
If you do not want to allocate the memory yourself, scanf can do it for you:
Note that the POSIX 2008 (2013) version of the
scanf()
family of functions supports a format modifier m (an
assignment-allocation character) for string inputs (%s, %c, %[).
Instead of taking a char * argument, it takes a char ** argument,
and it allocates the necessary space for the value it reads:
char *buffer = 0;
if (sscanf(data, "%ms", &buffer) == 1)
{
printf("String is: <<%s>>\n", buffer);
free(buffer);
}
If the sscanf() function fails to satisfy all the conversion
specifications, then all the memory it allocated for %ms-like
conversions is freed before the function returns.

Difference between gets() and scanf("%s") [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 3 years ago.
Improve this question
I declared a character pointer, and used it for to scan a string in runtime; I don't know the number of characters that I'm going to enter, so I didn't use calloc or malloc. The program ends when it reached the line scanf("%s", NewMsg_au8).
I'm using CodeBlocks 17.12 editor.
I tried hard coding one of the input case like, NewMsg_au8="0123456789ABCDEF"; — that works fine.
uint8 * NewMsg_au8;
scanf("%s",NewMsg_au8);//<==
printf("Your entered message is: %s\n",NewMsg_au8);
return NewMsg_au8;
gets(s) and scanf("%s", s) are both unsafe and potentially incorrect because:
with those calls as shown, there is no way for either function to determine the maximum number of characters to store into the array pointed to by s, hence overlong input will cause a buffer overrun leading to undefined behavior.
in your case, it is even worse as s is an uninitialized pointer, so both functions would try a store data into a random address in memory causing undefined behavior in all cases.
gets() cannot be used safely and has been deprecated in and then removed from the C Standard.
However, scanf() can be given a limit with a numeric value between % and s:
#include <stdio.h>
#include <string.h>
char *read_string(void) {
char buf[100];
if (scanf("%99s", buf) == 1) {
printf("Your entered message is: %s\n", buf);
return strdup(buf); /* return an allocated copy of the input string */
} else {
/* no input, probably at end of file */
return NULL;
}
}
Note how only 99 characters can be stored into the array buf to allow for the null byte terminator that marks the end of a C string. The %99s conversion specification lets scanf() store at most 100 bytes into buf, including the '\0' terminator.
That is a typical beginners error. You do not save data in pointers (with gets() or scanf()) but in buffers.
Therefore, you have 2 solutions:
Use an array big enough to hold the data. You have to decide yourself what "big enough" means, according to the details of your application.
Use a pointer, and then allocate memory with malloc() - the size, again, you have to decide it. Do not forget to deallocate the memory when you no longer need it.
I tried hard coding one of the input case like, NewMsg_au8="0123456789ABCDEF"; — that works fine.
That is normal, because in that case the compiler automatically allocates enough memory to hold the string.
Please always remember when working with strings: you always need to allocate an extra byte for the terminating null character - the mark of the end of the string. Otherwise, you will need to ask questions again :)

fopen() crashing on second use in c [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
for some reason, fopens keeps crashing in my program.
It works once when I am reading the input file and putting the contents into a variable. But for some reason, when I try to make it use fopens again, it crashes...
Could someone please help
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *buf = "\0";
char buffer[99999] ;
int main(int argc, char *argv[])
{
ptr_file =fopen(inputFileLocation,"r");
if (!ptr_file)
{
return 1;
}
while (fgets(buf,maxvalue, ptr_file)!=NULL)
{
strcat(buffer,buf);
}
fclose(ptr_file);
... //workings
//then the program crashes if I add an fopen() and fclose() at the end
}
The accepted answer misses the point. It is not only about buffer overrun.
There is no buffer overrun for maxvalue = 2; yet the program will crash.
But step by step:
fgets(buf, maxvalue, ptr_file) != NULL
The C library function char *fgets(char *str, int n, FILE *stream)
reads a line from the specified stream and stores it into the string
pointed to by str. It stops when either (n-1) characters are read,
the newline character is read, or the end-of-file is reached,
whichever comes first. A null character is automatically appended in
str after the characters read to signal the end of the C string.
In your case buf is string literal of size 2. This is quite likely too small for your needs.
But its not just about the size of buf!
You cannot copy anything to the (constant) string literal! That operation crashes your program with signal 11 even if you read one character.
Constants refer to fixed values that the program may not alter during its execution. These fixed values are also called literals.
What you need is a char array of the proper size.
You could either declare it the same way as char buffer[99999]
// 1.
char buf[SIZE_OF_THE_BUF]; // remember that buf has to accept maxvalue-1 characters + `null` character
or dynamically allocate memory for it in the main()
// 2.a
char *buf;
//
int main()
{
// 2.b
buf = malloc(maxvalue * sizeof(char));
//...
}
You create a pointer named buf that points to space containing a single character '\0'.
Then you use fgets() to try to read an unknown number of characters (you don't show what maxvalue is) into the space pointed to by buf. But that space is only one character long. Reading into it will overrun the space, causing undefined behavior.

strlen doesn't return the correct value with pointer to an array [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 6 years ago.
Improve this question
I have the following code:
char* realtor_command[120];
for(int i=0;i<REALTOR_MAX_COMMAND_LENGTH;i++){
realtor_command[i]=malloc(sizeof(120));
}
realtor_command[0]="test_string"
realtor_command[1]="next_test_string"
When I use strlen(realtor_command[0]) I get wrong value, I read in previous questions this happens because its an array and not pointer, yet I haven't found any fix for this problem.
My question is if there is anyway to get the length of realtor_command[i]?
Thank you very much.
EDIT :
This is how I invoke strlen :
char* matrix=malloc(strlen(realtor_command[8])+1);
In this code:
char* realtor_command[120];
for(int i=0;i<REALTOR_MAX_COMMAND_LENGTH;i++){
realtor_command[i]=malloc(sizeof(120));
}
You create an array of 120 strings, then loop through REALTOR_MAX_COMMAND strings (presumably this should be 120?) and set them to newly allocated 4- or 8-byte strings (sizeof(120) means sizeof(int) which is either 4 or 8 bytes). Since those strings are newly allocated, they will contain arbitrary data, and may not end with a null-terminator.
This is important because strlen() just loops over the string until it finds a null terminator, so it can't work with non-null-terminated strings.
You could add a null terminator yourself, but then the strings would contain arbitrary garbage up to the end of the string, and they may have null terminators inside them. You could make them start with a null-terminator, but then strlen() would always return 0.
What might be better is to allocate these strings when you actually fill them, and leave them as null pointers until then:
char* realtor_command[120];
for (int i = 0; i < 120; i++) {
realtor_command[i] = NULL;
}
char input_buffer[REALTOR_MAX_COMMAND];
// Read in one string, then copy it so we can re-use the buffer
fgets(input_buffer, REALTOR_MAX_COMMAND, stdin);
realtor_command[0] = strdup(input_buffer);
This will also avoid the memory leak in your code.
Note that you'll probably want to make sure the string read by fgets contains a newline, to make sure the input fit in your buffer:
if (strstr(input_buffer, "\n") == NULL) {
// error, input didn't fit in our buffer!
}

Inputting an arithmatic statement in c and return the value [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
(I am very bad at inputting/processing strings in C. Hope this question will teach me a lot.)
I am trying to make a function that will input an arithmatic string from stdin, e.g 23 + 45 * 6 - 5, and return the value.
There are multiple strings, entered one after another, and can be of any length and the operator precedence doesn't matter, i.e., it processes string sequentially.
The problems that I faced are :-
\n from previous string is also considered a string.So if I input 3 strings , it will actually be 6, 3 strings and 3 \n.
I used a char pointer and used char * input; scanf(" %s",input);, but in addition to above problem, I also get segmentation fault, which I guess is due to missing \0.
My question is forget what mess I did, what would you have done or what's the best way to handle string input in the above scenario. A dummy code is sufficient.Thanks.
What I was doing
#include <stdio.h>
int main()
{
int t; //no of test cases
char input;
scanf("%d",&t);
while(t--)
{
while((input=getchar())!='\n')
{
//use switch to identify char and follow appropriate action
printf("%c\n",input );
}
}
return 0;
}
As suggested by Joachim Pileborg, use fgets. Use a char array, instead of one char variable, to store the string.
char input[100];
fgets(input, sizeof(input), stdin);
The advantage of fgets over sscanf is that fgets can read spaces in your input.
It will include the end-of-line byte \n, so 3 strings will not turn into 6 strings.
As usual with fgets, there is an arbitrary limit on the length of the input. If the user inputs something longer than 98 bytes, the system cannot fit it all (plus end-of-line \n and end-of-string \0 bytes), and the program will receive truncated string.
If you cannot tolerate that, use getline (it's harder to use, so use fgets if in doubt).
After you scan your string in, check to see if it is a '\n', if it is just ignore processing it and move to the next one.
Or you could try:
char input[101];
scanf("%s\n", &input);
First of all. Your idea of writing an fomular expression analyzer as a first projekt is not a very good one. Start with a simpler project.
You get the sagmentation fault, because you try to read data (with the scanf()) into a not initialized pointer.
char *input;
will not allocate any memory for the string you want to read with scanf(). You have to use a buffer something like
char input[256];
and give the pointer to the buffer to scanf("%s",input) (oder for better understanding scanf("%s",&input[0]);
Anywhere, this buffer has only 255 chars to store and you must be aware, that if you enter more then 255 chars in the scanf() you will get an illegal memory access as well.
Claus

Resources