【问题标题】:Segmentation fault, I don't know why分段错误,我不知道为什么
【发布时间】:2018-01-24 14:06:13
【问题描述】:

我有一个段错误,但我不知道为什么。 我知道它应该可以工作,但它不断告诉我存在段错误,有人有解决方案吗? 请有人帮助我需要了解我的 BA。

#include <stdio.h>
#include <stdlib.h>

int split_allocate(const char* s, char*** word_array){
    char c;
    char tmp[100];
    int id_s,i=0, j=0,k;
    for(id_s =0 ; (c=s[id_s])!='\0' ; id_s++){
        printf("%c\n", c);
        if(c!=' ' && c!='\t' && c!='\n'){
            tmp[i]=c;
            i++;
            printf("i if : %d\n", i);
            continue;
        }
        tmp[i]='\0';
        printf("i else : %d & tmp : %s\n", i, tmp);
        (*word_array)[j] = (char*)malloc(sizeof(char)*(i+1));
        printf("666\n");
        if(NULL== (*word_array)[j]){
            return -1;
        }
        for(k=0 ; tmp[k] != '\0' ; k++){
            (*word_array)[j][k]=tmp[k];
        }
        (*word_array)[j][k+1]='\0';
        j++;
        printf("j for : %d\n", j);
        i=0;
    }
    return j;
}

int main(void) {
    char* s = "Salut,   cet examen\n a l'air long...";
    char*** word_array;
    printf("number of words :%d\n", split_allocate(s,word_array));
    return 0;
}

【问题讨论】:

  • word_array 是一个指针,但是它指向哪里?
  • 在不确定时使用具有自动存储持续时间的对象的值的未定义行为。
  • 另外,成为three-start programmer不是值得努力的事情。
  • 那么你应该将指针的地址传递给char,即char **word_array; split_allocate(..., &amp;word_array); And在函数中分配内存,比如*word_array = malloc(...)
  • (*word_array)[j][k+1] 我敢打赌它不会像你 @Sam45505 认为的那样做

标签: c segmentation-fault malloc


【解决方案1】:

我建议你更换

if(c!=' ' && c!='\t' && c!='\n')

if(!isspace(c))  // Iam easier and more readable

来自ctype.h。检测所有这些字符

' '      space 
'\t'     horizontal tab 
'\n'     newline
'\v'     vertical tab 
'\f'     feed 
'\r'     carriage return

另外你应该把char*** word_array;(三星级一般)改成pointer to pointer,这就够了。然后在heap 上分配内存(动态存储持续时间)。你没有这样做,它导致了segmentaion fault(取消引用未初始化的指针)。

char ** word_array = malloc (sizeof(char *) * ROWS);
for (int i = 0; i < ROWS; ++i)
{
    word_array[i] = malloc (sizeof(char) * ROW_LEN);
}

你不应该转换malloc()的返回值,因为它可能导致problems

您还应该检查行数,如果需要,请使用realloc 获取更多行,因为越界访问会导致undefined behavior


不要逐个字符地复制使用strcpy,因为你知道有足够的空间。它更具可读性和更容易。

for(k=0 ; tmp[k] != '\0' ; k++){
    (*word_array)[j][k]=tmp[k];
}

strcpy(word_array[j], tmp); // In case word_array is char **

我可以在你的字符串中看到空格,但你没有跳过它们,这可能会有所帮助

while ((c=s[id_s++]) && isspace(c))
    ;

【讨论】: