简体   繁体   中英

C Segmentation Fault 11

I am writing small program regards question on USACO.

Question is posted as http://usacotraining.blogspot.co.uk/2013/09/problem-112-greedy-gift-givers.html

Here is my code for it:

    /*
ID: xin.sun2
LANG: C
TASK: gift1
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int searchIndex(char *list[], char* s, int size) {
    for (int i = 0; i < size; i ++) {
        if (strcmp(list[i], s) == 0) {
            return i;
        }   
    }
    return -1;
}

int main() {

    freopen("gift1.in", "r", stdin);
    freopen("gift1.out", "w", stdout);

    int num_people = 0;
    scanf("%d", &num_people);

    char *nameList[num_people] = malloc(num_people*100*sizeof(char));
    int money[num_people];
    memset(money, 0, num_people*sizeof(int));

    for (int i = 0; i < num_people; i++) 
        scanf("%s", nameList[i]);

    char* this_people = malloc(100*sizeof(char));
    while (scanf("%s", this_people) != EOF) {
        int amount, num_giving, people_index;
        people_index = searchIndex(nameList, this_people, num_people);
        scanf("%d", &amount);
        scanf("%d", &num_giving);
        money[people_index] -= amount/num_giving*num_giving;
        int giving_amount = amount/num_giving;
        for (int i = 0; i < num_giving; i++) {
            char* p = malloc(100*sizeof(char));
            scanf("%s",p);
            int this_index = searchIndex(nameList, p, num_people);
            money[this_index] += giving_amount;
        }
    }

    for (int i = 0; i < num_people; i++) {
        printf("%s %d\n", nameList[i], money[i]);
    }

    return 0;
}

It has no problem when I compile the .c file, but when I execute file. It shows segmentation fault 11. I did try to use gdb and the result is

Program received signal SIGSEGV, Segmentation fault.
0x00007fff96b17908 in ?? ()

I have two questions: 1. What's wrong with my code (algorithms)? It might be syntax problem since I am really new to c programming 2. Why gdb shows ??() instead of the line number in main of where the problem is. Did I use gdb in the wrong way?

Thanks all!

UPDATE

I have correct the problem in regards to not sign space to array and char. but there is a compile error

null.c:27:8: error: variable-sized object may not be initialized
        char *nameList[num_people] = malloc(num_people*100*sizeof(char));

I have question about the correct way to initialise array of string and how to pass array of string as parameter to a function.

char* this_people;
while (scanf("%s", this_people) != EOF) {

and

char* p;
scanf("%s",p);

is wrong, this_people and p point to nowhere, and scanf uses this "nowhere" as input buffer. Either use malloc() to allocate some memory, or make p an array. (You'll still have problems if the user enters something that's longer than the space you provide, but as you're learning, that won't be a problem until later).

When you have a problem like this, the gdb command bt is your friend. It shows you which functions were called from where after a crash.

For the namelist array, you want to use:

define:

char **namelist;
namelist=malloc(num_people*sizeof (char *));

or, but this needs "new" compilers, as it isn't in old C specifications:

char *namelist[num_people];

then, in each of the 2 cases:

for (i=0; i<num_people; i++)
    namelist[i]=malloc(100);

(You should check if malloc returns NULL and throw an error, but i omitted that for brevity).

char* this_people;
while (scanf("%s", this_people) != EOF) {

this_people requires storage space. To be of the form

char this_people[100]; //or some desired maximum storage
while (scanf("%s", this_people) != EOF) {

Also,

char *nameList[num_people];

allocates a bunch of pointers of type char * . Not any storage.

  1. The segmentation fault occurs because you try to write to memory does not allocated by yourself, as pointed out by other answers. To fix these problems, you have several options, you can define them as a fixed-length array, dynamically allocate memories for them by calling malloc() , or use scanf("%ms", &p) and let the glibc do the memory allocation for you.

  2. GDB shows ?? () ?? () instead of line number and function name because it does not have enough information to show them. To fix this, you need to compile your program with -g (I suppose you are using gcc ) and install debug information packages for the system libraries (glibc in this case) that your program needed. If you are using Fedora or CentOS, you can install the debug information package for glibc by debuginfo-install glibc .

Your problem is there :

for (int i = 0; i < 5; i++) 
    scanf("%s", nameList[i]);

the pointer nameList[i] has not been associated to any allocated memory location. You need to do something like :

char *nameList[num_people];
for (int i=0; i<num_people; i++)
    nameList[i] = malloc(30*sizeof(char)); // or any size you choose

Same stands for :

char* this_people;

Also, to have precise details in gdb , you need to compile your program with the -g flag (if using GCC).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM