Segmentation fault (core dumped) need advising - arrays

I need help with allocating memory to my variables. I'm looking for specific lines that are causing the crash and how to fix them. I've tried reallocating and malloc in many places and in different ways. I have a rough idea about which lines are problematic (my realoc lines?).
int main() {
char * myString;// myString uesd to hold users input as entered
myString = input1(); //Get users input and stor it in myString
int sentence_count = 0; //To keep track of the total number of lines entered
sentence * sentences; //array of sentences to hold all the sentences as an instance of sentence
sentences = NULL;//initialize all values
myprint(sentence_count, sentences, myString);//Print word and lines
search(myString, sentence_count, sentences);//Search for word in sentences
free(myString);//free the memory set aside
return 0;
}
char * input1() {
char * line;// temporary variable to one hold input line
char * myString;//myString uesd to hold users input as entered
line = (char * ) malloc(1024 * sizeof(char));
myString = malloc(1024);
myString[0] = '\0';
line[0] = '\0';
while (line[0] != '\n') {
printf(" Please input a line : ");
fgets(line, 1000, stdin);
strcat(myString, line);//add line to mystring
}
free(line);
return myString;
}
I run it on Linux on PowerShell and get the following error
Segmentation fault (core dumped)

line = (char * ) malloc(1024 * sizeof(char));
myString = malloc(1024);
while (line[0] != '\n')
It is very clear here that, you did not initialize line character array. During first iteration, line[0] is unknown. Reading uninitialized variables is undefined behavior and can result in unexpected program behavior.

Related

Using gdb--still can't find malloc error

I've looked at previous posts about this and they didn't help me locate my problem... To keep it short I'm making a function should read a text file line by line (and yes, I do realize there are many posts like this). But when I run my program through CMD, it's giving me this error:
Program received signal SIGSEGV, Segmentation fault.
__GI___libc_realloc (oldmem=0x10011, bytes=1) at malloc.c:2999
2999 malloc.c: No such file or directory.
I'm pretty sure I wrote out my malloc/realloc lines correctly. I've tried finding alot of posts similar to this, but none of the solutions offered are helping. If you have any post suggestions that maybe I missed, please let me know. Regardless, here are my functions:
char* read_single_line(FILE* fp){
char* line = NULL;
int num_chars = 0;
char c;
fscanf(fp, "%c", &c);
while(!feof(fp)) {
num_chars++;
line = (char*) realloc(line, num_chars * sizeof(char));
line[num_chars -1] = c;
if (c == '\n') {
break;
}
fscanf(fp, "%c", &c);
}
if(line != NULL) {
line = realloc(line, (num_chars+1) * sizeof(char));
line[num_chars] = '\0';
}
return line;
}
void read_lines(FILE* fp, char*** lines, int* num_lines) {
int i = 0;
int num_lines_in_file = 0;
char line[1000];
if (fp == NULL) {
*lines = NULL;
*num_lines = 0;
} else {
(*lines) = (char**)malloc(1 * sizeof(char*));
while (read_single_line(fp) != NULL) {
(*lines)[i] = (char*)realloc((*lines)[i], sizeof(char));
num_lines_in_file++;
i++;
}
*lines[i] = line;
*num_lines = num_lines_in_file;
}
}
I would really appreciate any help--I'm a beginner in C so hear me out!!
char line[1000];
:
while (read_single_line(fp) != NULL) {
:
}
*lines[i] = line;
This doesn't look at all right to me. Your read_single_line function returns an actual line but, other than checking that against NULL, you never actually store it anywhere. Instead, you point the line pointer to line, a auto-scoped variable which could contain literally anything (and, more worrying, possibly no terminator character).
I think you should probably store the return value from read_single_line and use that to set your line pointers.
By the way, it may also be quite inefficient to expand your buffer one character at a time. I'd suggest initially allocating more bytes and then keeping both that capacity and the bytes currently in use. Then, only when you're about to use beyond your capacity do you expand, and by more than one. In pseudo-code, something like:
def getLine:
# Initial allocation with error check.
capacity = 64
inUse = 0
buffer = allocate(capacity)
if buffer == null:
return null
# Process each character made available somehow.
while ch = getNextChar:
# Expand buffer if needed, always have room for terminator.
if inUse + 1 == capacity:
capacity += 64
newBuff = realloc buffer with capacity
# Failure means we have to release old buffer.
if newBuff == null:
free buffer
return null
# Store character in buffer, we have enough room.
buffer[inUse++] = ch
# Store terminator, we'll always have room.
buffer[inUse] = '\0';
return buffer
You'll notice, as well as the more efficient re-allocations, better error checking on said allocations.
while (read_single_line(fp) != NULL) {
(*lines)[i] = (char*)realloc((*lines)[i], sizeof(char));
num_lines_in_file++;
i++;
}
*lines[i] = line;
There are more errors then lines in this short fragment. Let's go over them one by one.
while (read_single_line(fp) != NULL)
You read a line, check whether it's a null pointer, and throw it away instead of keeping it around to accumulate it in the lines array.
(*lines)[i] = (char*)realloc((*lines)[i], sizeof(char));
You are trying to realloc (*lines[i]). First, it does not exist beyond i==0, because (*lines) was only ever allocated to contain one element. Second, it makes no sense to realloc individual lines, because you are (should be) getting perfect ready-made lines from the line reading function. You want to realloc *lines instead:
*lines = realloc (*lines, i * sizeof(char*));
Now these two lines
num_lines_in_file++;
i++;
are not an error per se, but why have two variables which always have the exact same value? In addition, you want them (it) be before the realloc line, per usual increment-realloc-assign pattern (you are using it in the other function).
Speaking of the assign part, there isn't any. You should insert one now:
(*lines)[i-1] = // what?
The line pointer you should have saved when calling read_single_line, that's what. From the beginning:
char* cur_line;
int i = 0;
*lines = NULL;
while ((cur_line=read_single_line(fp)) != NULL)
{
++i;
*lines = realloc (*lines, i * sizeof(char*));
(*lines)[i-1] = cur_line;
}
*num_lines = i;
The last one
*lines[i] = line;
is downright ugly.
First, lines is not an array, it's a pointer pointing to a single variable, so lines[i] accesses intergalactic dust. Second, you are trying to assign it an address of a local variable, which will cease to exist as soon as your function returns. Third, what is it doing outside of the loop? If you want to terminate your line array with a null pointer, do so:
}
*num_lines = i;
++i;
*lines = realloc (*lines, i * sizeof(char*));
(*lines)[i-1] = NULL;
But given that you return the number of lines, this may not be necessary.
Disclaimer: none of the above is tested. If there are any bugs, fix them!

Stack Smashing Detected - Aborted (core Dumped)

I cannot seem to find why this is stack smashing, the code is meant to read in some files, read each line and cat other lines on the end. but i get a stack smashing detected error at the very end of code.
Any ideas?
Code is :
void main (int argc, char *argv[])
{
char lineCount;
int count = 0;
size_t buffer_size = 40;
char *buffer =malloc(buffer_size * sizeof(char));
char *buffer2 =malloc(buffer_size * sizeof(char));
char *buffer3 =malloc(buffer_size * sizeof(char));
char *buffer4 =malloc(buffer_size * sizeof(char));
FILE *Dictionary, *Names;
Dictionary = fopen ("/home/overdog/Documents/Coding/dictionary.txt","r");
Names = fopen ("/home/overdog/Documents/Coding/rawnames.txt","r");
while(-1 != getline(&buffer,&buffer_size,Dictionary))
{
count = count + 1;
for (int i =1; i <= 10; i++)
{
memcpy(buffer2,buffer,buffer_size);
char num[1];
RemoveEndLine(buffer2);
sprintf(num,"%d",i);
strcat(buffer2,num);
printf("%s\n",buffer2);
while(-1 != getline(&buffer3,&buffer_size,Names))
{
memcpy(buffer4,buffer2,buffer_size);
printf("before break\n");
strcat(buffer4,buffer3);
printf("%s",buffer4);
}
}
}
printf("Lines = %d \n",count);
free(buffer);
free(buffer2);
free(buffer3);
free(buffer4);
fclose(Dictionary);
fclose(Names);
printf("test\n");
}
The output seems OK, and the print of "test" at the end of the code prints. And then the Stack smashing error is seen.
Lets take a close look at these two lines:
char num[1];
...
sprintf(num,"%d",i);
You declare num as an array of a single character, forgetting that (char) strings in C are really called null terminated byte strings. That means a string of a single character needs space for two char elements, to fit the terminator.
Since you don't have space for the terminator then sprintf will write out of bounds of your array, leading to undefined behavior and your smashed stack.
If you are certain that the number will never be more than a single digit (which it wont, it will include the two-digit number 10), then you need to have an array of at least two character elements.
I also recommend you use snprintf to avoid buffer overflows like that.
thanks for all the help, what Some Programmer Dude said did help i think but i still had an issue. I found that the issue was the line
strcat(buffer4,buffer3);
As the buffer size for both was the same, it was creating a string which requires a buffer of 80?
i amended the line
char *buffer4 =malloc(buffer_size * sizeof(char));
to read
char *buffer4 =malloc(80 * sizeof(char));
And this now works without stack smashing
Thanks!

Segmentation fault when dividing string using malloc

I am using ncurses to create my own terminal. I get the string and save it in a 2D array, buffer[80][256]. I get the string using getstr(buffer[i]). Then I have the following in the main function;
while (strcmp(buffer[i],"exit")!=0) {
strcpy(command,buffer[i]);
printw("%s\n",command);
//calls the function commands found in another source file
commands(buffer[i]);
mvwin(childwin, y, x);
wnoutrefresh(childwin);
i++;
printw("%s",prompt);
getstr(buffer[i]);
doupdate();
}
//source file where one finds commands;
//global array
char*final[40];
void commands (char input[]){
char **buffer =split(input);
...
}
//creating segmentation fault
char **split(char input[]){
char *ptr;
int i=0;
ptr = strtok(input," ");
while(split != NULL){
final[i] = malloc(strlen(ptr)+1);
strcpy(final[i],ptr);
ptr = strtok(NULL," ");
i++;
}
return final;
}
What the above function is doing; it is receiving the input by the user buffer[i] and it is dividing the strings into separate elements within array buffer in function commands. e.g. if the user enters print hello my name is, buffer in function commands with hold; buffer[0] = print, buffer[1] = hello buffer[2] = my ....
From my testing it seems like the malloc is the thing causing it, but I have no idea on how to solve it.
Thank you very much in advance.
while(split != NULL){
Instead of check split for NULL you need to check if ptr is NULL.
If it is NULL then your malloc will allocate 1 byte and memory's dereference will cause problems due to overflow.

Segmentation fault when calling fgets to read lines from file

I'm getting a seg fault when after calling fgets about 20 times. I'm opening a file (does not return null). It is in the format:
num1: value1
num2: value2
num3: value3
then reading lines from the file, storing values into an array, using nums as positions. Here is the code that seg faults:
edit: declaring myArray and line:
char myArray[3000];
char * line;
char * word;
line = (char *) malloc(100);
word = (char *) malloc(16);
while(fgets(line, 99, file)) {
printf("%s\n", line);
word = strtok(line, " :");
name = (int) strtol(word, NULL, 16);
word = strtok(NULL, " \n");
myArray[name] = word;
}
you'll notice I print out the line immediately after getting it. The file has 26 lines, but it only prints 23 line and then seg faults. Now, is it something I don't fully understand about fgets, or am I getting some synthax incorrect? I've tried allocating more memory to line, or more to word. I've also tried malloc -ing more memory after every call to strtok, but nothing seems to fix the seg fault.
The problems is the line myArray[name] = word; you're taking an array index from your input line and then setting the character at that position to low bits of the address of your word... I doubt that's actually what you want to do.
There's some other problems with your code, you're leaking the memory from the line word = (char *) malloc(16); because strtok returns a pointer into the string you initially pass it. You don't actually need to malloc anything for the code as written in the question, so you could have:
char myArray[3000];
char line[100];
char *word = NULL;
word needs to be a pointer since it's holding the result of strtok()
You clearly don't understand pointers, you need to review that before you can understand why your code isn't working the way you expect.
If you say what your code is actually meant to be doing I can give you some hints on how to fix it, but at the moment I can't quite tell what the intended result is.
EDIT: Did you intend to read in your numbers in hexadecimal? The last argument to strtol() is the base to be used for conversion... you could also just use atoi()
so your loop could look like:
char myArray[3000];
char line[100];
char *word = NULL;
while(fgets(line, 100, file)) {
printf("%s\n", line);
word = strtok(line, " :");
if(word == NULL) continue;
name = atoi(word); /* only if you didn't actually want hexadecimal */
word = strtok(NULL, " \n");
if(word == NULL) continue;
if(name > 0 && name < 3000) { /* as I said in a comment below */
strncpy(myArray + name, word, 3000 - name);
}
}

How can I read a file word by word using stdio.h in C?

I'm new to C and I can't quite get it without a segmentation fault.
Here's my idea so far:
#include<stdio.h>
#include<string.h>
char *nextWord(FILE *stream) {
char *word;
char c;
while ( (c = (char)fgetc(stream)) != ' ' && c != '\n' && c != '\0') {
strcat(word, &c);
}
return word;
}
int main() {
FILE *f;
f = fopen("testppm.ppm", "r");
char *word;
word = nextWord(f);
printf("%s",word);
}
In your nextWord function, you never initialize the local variable word to point at anything, so when you try to write to the pointed-at memory with strcat, you get a segfault.
You need to allocate memory to store the word that you are going to read. The problem is, you don't know how big that word will be, so you don't know how much space to allocate. There are a number of possible approaches:
Use a (large) fixed size buffer on the stack to hold the word as you read it, then copy it to a malloc'd area of the appropriate size when you return it. There will be problems if you encounter a word that is too big for your fixed size buffer.
allocate a small block to read the word into, and keep track of how much is used as you read characters. When the block is full, realloc it to be bigger.
Or you can also use the fscanf function in your while loop.
char *nextWord(FILE *stream) {
char *buffer[124], *word;
int previous_size = 0;
while(!feof(!stream)){
int n = fscanf(file, "%s", buffer);
if(word == NULL){
word = malloc(sizeof(char)*n)
} else {
realloc(word, n + previous_size);
}
strncat(word, buffer, strlen(buffer) - 1);
previous_size = n;
}
return word;
}
A little explanation. The function fscanf returns the number of characters read. So the first thing i do is to save that value. If word is NULL you allocate it with the number of character otherwise you allocate word with the previous_size variable.
Don't forget to flush the buffer variable

Resources