[英]C Segmentation Fault 11
我在USACO上写小程序有关问题。
问题被发布为http://usacotraining.blogspot.co.uk/2013/09/problem-112-greedy-gift-givers.html
这是我的代码:
/*
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;
}
当我编译.c文件时,但是当我执行文件时,它没有问题。 它显示了分段错误11。我确实尝试使用gdb,结果是
Program received signal SIGSEGV, Segmentation fault.
0x00007fff96b17908 in ?? ()
我有两个问题:1.我的代码(算法)有什么问题? 可能是语法问题,因为我真的是C编程2的新手。为什么gdb在问题所在的main中显示??()而不是行号。 我是否以错误的方式使用gdb?
谢谢大家!
UPDATE
我已经纠正了有关不对数组和char签名空间的问题。 但是有一个编译错误
null.c:27:8: error: variable-sized object may not be initialized
char *nameList[num_people] = malloc(num_people*100*sizeof(char));
我对初始化字符串数组的正确方法以及如何将字符串数组作为参数传递给函数有疑问。
char* this_people;
while (scanf("%s", this_people) != EOF) {
和
char* p;
scanf("%s",p);
是错误的,this_people和p指向无处,而scanf使用此“无处”作为输入缓冲区。 使用malloc()分配一些内存,或将p设置为数组。 (如果用户输入的内容长于您提供的空间,您仍然会遇到问题,但是在您学习时,直到稍后才出现问题)。
当您遇到这样的问题时,gdb命令bt
是您的朋友。 它显示崩溃后从何处调用了哪些函数。
对于名称列表数组,您要使用:
限定:
char **namelist;
namelist=malloc(num_people*sizeof (char *));
或者,但这需要“新”编译器,因为它不在旧的C规范中:
char *namelist[num_people];
然后,在这两种情况下:
for (i=0; i<num_people; i++)
namelist[i]=malloc(100);
(您应该检查malloc是否返回NULL并抛出错误,但是为了简洁起见,我省略了该操作)。
char* this_people;
while (scanf("%s", this_people) != EOF) {
this_people需要存储空间。 形式
char this_people[100]; //or some desired maximum storage
while (scanf("%s", this_people) != EOF) {
也,
char *nameList[num_people];
分配一堆char *
类型的指针。 没有任何存储空间。
出现分段错误是因为您尝试写入未由您自己分配的内存,如其他答案所指出的。 要解决这些问题,您有几种选择,可以将它们定义为固定长度的数组,可以通过调用malloc()
为它们动态分配内存,或者使用scanf("%ms", &p)
并让glibc进行内存处理为您分配。
GDB显示?? ()
?? ()
代替行号和函数名,因为它没有足够的信息来显示它们。 要解决此问题,您需要使用-g
编译程序(我想您正在使用gcc
),并为程序所需的系统库(在本例中为glibc)安装调试信息包。 如果使用的是Fedora或CentOS,则可以通过debuginfo-install glibc
的调试信息包。
您的问题在那里:
for (int i = 0; i < 5; i++)
scanf("%s", nameList[i]);
指针nameList[i]
尚未与任何分配的内存位置相关联。 您需要执行以下操作:
char *nameList[num_people];
for (int i=0; i<num_people; i++)
nameList[i] = malloc(30*sizeof(char)); // or any size you choose
同样代表:
char* this_people;
另外,要在gdb
获得准确的详细信息,您需要使用-g
标志(如果使用GCC)编译程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.