Why do I get segmentation fault in my code? - c

I keep getting segmentation fault, how can I fix that. I tryed more variants but I get segmentation fault everytime when I am using if statements. My code is something similar with this:
#include <stdio.h>
#include <string.h>
int main()
{
int i;
char *sentence[300];
fgets(*sentence,300,stdin);
int length=strlen(*sentence);
for(i=0;i<length;i++){
if(sentence[i]=="a")
printf("qwer");
else if(sentence[i]=="b")
printf("asdf");
else if(sentence[i]=="c")
printf("zxcv");
// ...
}
return 0;
}

The first thing you're doing wrong is this:
char *sentence[300];
It looks like you're trying to create a buffer of 300 characters, but what you're really doing is creating an array of 300 character pointers. Change that to:
char sentence[300];
Then you want to change this:
fgets(*sentence,300,stdin);
to
fgets(sentence,sizeof(sentence),stdin);
Then you want to change
int length=strlen(*sentence);
to
int length=strlen(sentence);
You need to have a good understanding of how strings work in C. If you haven't read a good introductory book for C, start there. C is not something you're going to pick up by just reading random pages on the web and StackOverflow.

Related

comparing array contents for counter purposes [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 3 months ago.
I'm trying to set up a comparison between an array and a given string.
The idea being, that if i started building structures with multiple objects in them, that i could test for a key word in said structure and set up a counter to see how often that element is contained within that structure.
Though this doesnt seem to work, as the terminal output i get is the "ohnoo". Hence I'm thinking that there is something wrong with the comparison in line 8.
The compiler sees nothing wrong with the following code, so its hard to find a solution by myself.
Here's a simple piece of code i tried to test this idea with.
#include <stdio.h>
#include <string.h>
char string1[10] = "Automatic";
int main()
{
if(string1 == "Automatic")
{
printf("huzzah\n");
}
else{
printf("ohnoo\n");
}
}
Strings in C cannot be compared in this way. Rather use strcmp. Otherwise, using == you are determining if they point to the same location in memory, rather than whether their contents are the same.
#include <stdio.h>
#include <string.h>
char string1[10] = "Automatic";
int main()
{
if (strcmp(string1, "Automatic") == 0)
{
printf("huzzah\n");
}
else{
printf("ohnoo\n");
}
}

Double Dynamic Array

This is my first time working with dynamic arrays and I am honestly just so confused. My original array(below) works fine.
#include <stdio.h>
int main()
{
char icdC[4][10];
for(int i =0;i<4;i++){
for(int j=0;j<10;j++){
printf("What are your ICD codes [%d][%d]\n",i,j);
scanf("%s", &icdC[i][j]);
}
}
return 0;
}
However I tried converting this array into a double dynamic array (below) it doesn't seem to work correctly as it will either tell me "signal: segmentation fault (core dumped) or it just won't run.
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
int main()
{
char** icdC;
icdC = (char**)malloc(4*10*sizeof(char));
for(int i=0;i<4;i++){
for(int j=0;j<10;j++){
printf("What are your ICD codes [%d][%d]\n",i,j);
scanf("%s", &icdC[i][j]);
}
}
return 0;
}
The issue seems to be located within icdC = (char**)malloc(4*10*sizeof(char));, as it is an incorrect reference to the second array you're trying to create.
In C there are many options to represent a 2d array, among which the possibility to
create an array of pointers, each of which points to a specific row. Then you can allocate the memory for each array using the malloc, which allows you to generate an "array of pointers".
The implementation would most likely be:
char ** icdC;
int r = 4, c = 10;
icdC = (char*) malloc(sizeof(char*) * r);
for (int i = 0; i < r; i++) {
icdC[i] = malloc(sizeof(char) * c);
}
Note: You can also do this implementation in two loops as you did above.
From here you can do a nested loop to scan the value like you've already done in your snippet. Remember that now you can access a value by indicating the index for the corresponding row and column, like this: icdC[row_num][row_column] = .....
It might look strange at the beginning, but after you get a grasp of the concept, it's all good and fun!

Getting segmentation fault when indexing a 'mallocced' array

I've been struggling with this one for a few hours now and I'm at a loss as to what's happening. This is the code for program.c:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define SPACE 32
#define INITIAL 4
typedef struct {
char *town;
char *country;
} town_t;
typedef struct {
int num_towns, current_size;
town_t **towns_list;
} index_t;
int main(int argc, char *argv[]) {
index_t town_index;
town_index.current_size = INITIAL;
town_index.towns_list = malloc(town_index.current_size * sizeof(*(town_index.towns_list)));
assert(town_index.towns_list != NULL);
printf("Step: %d\n", 1);
town_index.towns_list[0]->town = malloc(4 * sizeof(*(town_index.towns_list[0]->town)));
printf("Step: %d\n", 2);
assert(town_index.towns_list[0]->town != NULL);
return 0;
}
On Linux this is how it runs:
./program
Step: 1
Segmentation fault
but on Windows it prints out
program.exe
Step: 1
Step: 2
as I'd expect, which really isn't helping. For the Linux output, however, clearly the first print statement is being executed but not the second, which would lead me to think that the line between is that one at fault. Particularly, I think doing town_index.towns_list[0] is causing me issues, but I cannot say why.
This is a relatively complex data structure, so maybe I'm getting lost at some point. Basically town_index is meant to be a index struct that contains the current number of towns in towns_list and current_size which reflects the space currently available to save towns. It also contains an array of pointers to town_ts which contain the name and country as strings.
I've tried to use Valgrind, but it's really not helping out much. Here's a Pastebin for those who want to see.
This is a simplified scenario of what I was experiencing in another program, so don't any mind magic numbers and whatnot.
This is on VirtualBox Linux Mint 64-bit.
Unrelated question, if anyone can: How do I get Valgrind to display the precise lines? I see that everywhere else online, but my output just tells me the folder in which the program and function is, which isn't much help.
You initialized town_index.towns_list, but not town_index.towns_list[0], so town_index.towns_list[0]->town is undefined behaviour.
You missed something like
for (int i = 0; i < town_index.current_size; ++i)
town_index.towns_list[i] = malloc(sizeof **town_index.towns_list);
for the second dimension.
town_index.towns_list and town_index.towns_list[0] are not the same. You initialize town_index.towns_list but town_index.towns_list[0] is equal to 0. The crash caused by dereferencing town_index.towns_list[0]

Segmentation fault - C language - Struct and For loop

I am getting a segmentation fault when i am running the below:
The printf is only for testing the result, as i want to get this info and add it in another array.
#include <stdio.h>
#include <string.h>
struct proion
{
char onoma[30];
float timi;
int stock;
};
int main()
{
int i;
for (i=0;i<=200;i++)
{
struct proion proion[i];
strcpy (proion[i].onoma,"test");
proion[i].timi=5;
proion[i].stock=10;
printf("%s\n%.2f\n%d\n",proion[i].onoma, proion[i].timi,proion[i].stock);
}
return 0;
}
allocate memory In the for loop you are creating an array for Proion.
First loop is:
struct proion proion[0];
So when you access proion[i] you get a segmentation fault since there is no memory allocated for that variable.
This will be also true for other loops because you are access the ith element of the array but you only have 0 to i-1 elements.
The approach is however wrong. Seems like you are trying to create 200 structs. In that case just create the array outside the loop or use malloc to allocate memory dynamically.
You likely mean to say:
struct proion proion[200];
for (i = 0; i < 200; i++)
{
strcpy(proion[i].onoma, "test");
Currently, you're creating a new array each time, e.g. when i == 5, it's like you're saying:
struct proion proion[5];
strcpy (proion[5].onoma,"test");
which will write to the struct just past the end of the array (causing the segmentation fault). And, of course, the whole array is thrown away after every loop.
Also note, in the corrected version, we say i < 200, not i <= 200, if we're working with an array of size 200.

Allocating memory inside a function and returning it back

I want to pass a pointer to my function and allocate the memory to which this pointer points. I've read in other posts that I should pass a double pointer to this function and I did so, but I keep getting segmentation fault:
#include <iostream>
#include <stdlib.h>
using namespace std;
void allocate(unsigned char** t)
{
*t=(unsigned char*)malloc(3*sizeof(unsigned char));
if(*t == NULL)
cout<<"Allcoation failed"<<endl;
else
for(int m=0;m<3;m++)
*(t[m])=0;
}
int main()
{
unsigned char* t;
allocate(&t);
cout<<t[0]<<" "<<t[1]<<endl;
return 0;
}
the result is always this:
Segmentation fault (core dumped)
I don't think that there's anything missing from this code. What could be wrong?
Look at this line: *(t[m]) = 0;. Since you have given t[m] precedence, it will look for the m-th pointer to char and dereference that. What you actually want to do is dereference t and find the char m places after that, or (*t)[m]. Making this change causes your code to work perfectly: http://ideone.com/JAWeS2
I think this line is treading where it shouldn't:
*(t[m])=0;
Consider the case where m is 2. That's unallocated memory you're writing to. You've done nothing to claim it from the runtime heap.
You may be thinking of something like this:
t[0][m]=0;

Resources