返回int值时的Segfault;

时间:2012-02-17 00:51:53

标签: c segmentation-fault

我知道这个问题可能听起来很愚蠢,但我已经尽了最大努力,似乎无法用这段代码解决问题:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

int ind = 0;
char** yay = strsplit(code, ";");
char* a = *yay;

while (a != NULL) {

    puts(a);

    if (strncmp(a, "#", 1)) {
        struct bacon_statement statm;
        int valid = bacon_make_statement(a, statm);
        if (valid != 0) { return valid; }

        statms[sta] = statm;
    }

    sta++;
    *(yay)++;
    a = *yay;
}

puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;

return时段错误,因为printf执行正常。而另一个printf调用/之后调用该函数(在int main()上)什么都不打印。

如果这听起来太具体,我很抱歉,但我不知道还能在哪里获得帮助。

5 个答案:

答案 0 :(得分:3)

显然你正在以某种方式破坏堆栈。 你的行没有初始化指针:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

但你这样写它会有不明确的行为:

statms[sta] = statm;

最简单的修复方法可能是恢复malloc(假设大小正确)

struct bacon_statement* statms = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

答案 1 :(得分:2)

看起来像堆栈溢出,您继续将数据分配给缓冲区(statms)而不检查边界。迟早,将覆盖返回地址(在堆栈上),当达到返回时,返回的地址将被破坏。并且存在您的分段错误。

答案 2 :(得分:1)

尝试做类似的事情:

int count = 0;
char *ptr = strchr(code, ';');
while (ptr) {
    count++;
    ptr = strchr(ptr + 1, ';');
}

预测语句数量,然后:

struct bacon_statement* statms = (struct bacon_statement*) malloc(
    count * sizeof(struct bacon_statement));

分配足够的bacon_statement个广告位。替代方案可能更难:链表或其他可变结构;或者使用realloc来增加数组的大小,记下你剩下的多少个。

但错误仍然可以在其他功能中使用!

答案 3 :(得分:1)

代码做得太多了。让我总结一下:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

int ind = 0;
char** yay = strsplit(code, ";");
char* a;

while ((a = *yay)) {

    puts(a);

    if (strncmp(a, "#", 1)) {
        struct bacon_statement statm;
        int valid = bacon_make_statement(a, statm);
        if (valid != 0) { return valid; }

        statms[sta] = statm;
    }

    sta++;
    *(yay)++;
}

puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;

但我们可以比这更紧凑:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

int ind = 0;
char** yay;;
char* a;

for (yay = strsplit(code, ";"); (a = *yay); *(yay)++ ) {

    puts(a);

    if (strncmp(a, "#", 1)) {
        struct bacon_statement statm;
        int valid = bacon_make_statement(a, statm);
        if (valid != 0) { return valid; }

        statms[sta] = statm;
    }

    sta++;
}

puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;

现在让我们删除愚蠢的字符串:

struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

int ind = 0;
char** yay;
char* a;

for (yay = strsplit(code, ";"); (a = *yay); *(yay)++ ) {

    puts(a);

    if (*a != '#') {
        struct bacon_statement statm;
        int valid = bacon_make_statement(a, statm);
        if (valid != 0) { return valid; }

        statms[sta] = statm;
    }

    sta++;
}

puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;

仍然没有意义。 IMO OP想要循环一个字符串指针数组(yay)并处理其中的每个字符串。特别是*(yay)++看起来很尴尬。

也许与#'#'他想跳过评论。我期待的是:

sta=0;
for (yay = strsplit(code, ";"); (a = *yay); yay++ ) {
    int err;
    if (*a == '#') continue;
    /* make bacon from a */
    err = bacon_make_statements(a, statms[sta] );
    if (err) return err;
    sta++; /* could overflow ... */
    }

 /* you need the number of assigned struct members ("sta") to this function */
 return bacon_internal_make(statms,sta internal);

第二个想法,我的猜测是strsplit()函数返回一个指向自动(" stack")变量的指针。或* yay变量增加超出识别。或者statms []数组被索引越界。

答案 4 :(得分:0)

您是否有可能使用 ind 而不是 sta 作为数组索引变量并且< strong> sta 未初始化?