【问题标题】:Segmentation fault with array of strings C字符串数组C的分段错误
【发布时间】:2014-03-06 21:36:15
【问题描述】:

我编写了一个程序,它将一个字符串分解为由空格分隔的标记,然后将每个单独的字符串复制到一个字符串数组中。

程序运行良好,直到它到达 for 循环,并且在成功将第一个字符串添加到数组并打印后,程序崩溃。我调试了一下,发现

args[i] = malloc((strlen(comm_str) + 1) * sizeof(char));

返回SEGFAULT 然后第二次执行循环。调用堆栈也打印出以下内容:

地址:75F943F9,函数:strlen(),文件:C:\Windows\syswow64\msvcrt.dll。`

我尝试自己更正程序,但没有结果。起初我以为循环试图访问超出绑定区域,但我认为我已经正确地 malloc'd 一切。

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

int main(){

    char **args = NULL;
    char input[] = "cmdline -s 20 -r -t parameter -p 20 filename";

    int num = 0;
    char *comm_str = strtok(input, " ");                            /*Tokens command line*/

    while(comm_str != NULL){                                        /*Counts number of tokens*/
        num++;
        printf("%s %d\n", comm_str, strlen(comm_str));
        comm_str = strtok(NULL, " ");
    }
    printf("\n");

    args = malloc(num * sizeof(char*));                          /*Allocates memory for the first string entry*/
    if(!args){
        return 0;
    }

    comm_str = strtok(input, " ");                                  /*Starts tokening from beginning*/
    for(int i = 0; i < num; i++){
        args[i] = malloc((strlen(comm_str) + 1) * sizeof(char));    /*Allocates memory for strings*/
        if(!args[i]){
            for(int b = 0; b < i; b++){
                free(args[b]);
            }
            free(args);
            return 0;
        }
        strcpy(args[i], comm_str);
        printf("%s\n", args[i]);
        comm_str = strtok(NULL, " ");
    }

    printf("%d\n", num);

}

【问题讨论】:

  • "返回 SEGFAULT 然后 [...]" - 再来一次?
  • 您可能忘记正确分配内存。 args[0...num-1] 也应该是 malloc 的。 “然后返回 SEGFAULT...”听起来不对。
  • 我认为thenwhen 的拼写错误
  • @vpit3833 他在 malloc 时遇到了段错误。
  • 否,然后 i=0,循环执行没有问题并打印出“cmdline”,但之后 (i=1) at 'args[i] = malloc((strlen(comm_str) + 1 ) * sizeof(char));'发生 SEGFAULT。

标签: c arrays string segmentation-fault


【解决方案1】:

strtok,如您所知,正在更改字符串。

计算单词数后,字符串将包含一个单词。因此下一个strtok 将返回NULL。

以非破坏性方式计算参数的数量,或制作字符串的副本。

【讨论】:

  • 知道了!不知道 strtok 会更改原始字符串,但现在我制作了它的第二个副本,并且 for 循环按预期工作。谢谢你的帮助。
【解决方案2】:

根据 strtok 的手册页: “使用这些功能时要小心。如果您确实使用它们,请注意: 这些函数修改它们的第一个参数。 这些函数不能用于常量字符串。”

所以,第一次解析找到 num 时,修改了输入字符串,因此第二次解析垃圾,这会导致 SEGFAULT。另外,你不应该使用常量字符串:

char input[] = "cmdline -s 20 -r -t parameter -p 20 filename";

【讨论】:

    【解决方案3】:

    第一个问题是你没有包含相关的函数原型。这将使它假设一切都是整数。见下文:

    $ gcc -Wall x.c -o x
    x.c: In function ‘main’:
    x.c:9:5: warning: implicit declaration of function ‘strtok’ [-Wimplicit-function-declaration]
    x.c:9:22: warning: initialization makes pointer from integer without a cast [enabled by default]
    x.c:13:9: warning: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
    x.c:13:37: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
    x.c:13:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat]
    x.c:14:18: warning: assignment makes pointer from integer without a cast [enabled by default]
    x.c:18:5: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
    x.c:18:12: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
    x.c:23:14: warning: assignment makes pointer from integer without a cast [enabled by default]
    x.c:24:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
    x.c:24:5: note: use option -std=c99 or -std=gnu99 to compile your code
    x.c:25:27: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
    x.c:27:13: error: ‘for’ loop initial declarations are only allowed in C99 mode
    x.c:28:17: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
    x.c:28:17: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
    x.c:30:13: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
    x.c:33:9: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration]
    x.c:33:9: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default]
    x.c:35:18: warning: assignment makes pointer from integer without a cast [enabled by default]
    x.c:40:1: warning: control reaches end of non-void function [-Wreturn-type]
    

    我建议你在继续之前解决这个问题。

    【讨论】:

    • 我已经包含了#include 、#include 和#include ,我的编译器没有返回任何警告。
    【解决方案4】:

    strtok 在您的情况下将每个 ' ' 替换为 NULL。考虑以下几点:

    char input[] = "cmdline -s 20 -r -t parameter -p 20 filename";
    size_t inputSize = strlen(input);
    
    for(int i = 0; i < inputSize; i++)
        printf("%02X ", input[i]);
    printf("\n\n");
    
    char *comm_str = strtok(input, " "); 
    while(comm_str != NULL)
        comm_str = strtok(NULL, " ");
    
    for(int i = 0; i < inputSize; i++)
        printf("%02X ", input[i]);
    printf("\n\n");
    

    输出:

    63 6D 64 6C 69 6E 65 20 2D 73 20 32 30 20 2D 72 20 2D 74 20 70 61 72 61 6D 65 74 65 72 20 2D 70 20 32 30 20 66 69 6C 65 6E 61 63 6D 64 6C 69 6E 65 00 2D 73 00 32 30 00 2D 72 00 2D 74 00 70 61 72 61 6D 65 74 65 72 00 2D 70 00 32 30 00 66 69 6C 65 6E 61

    【讨论】:

      猜你喜欢
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-15
      • 2021-07-12
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多