解决指向字符串指针的指针中的分段错误

gn6*_*n66 1 c arrays string multidimensional-array

当我想在动态数组中保存字符串时,我遇到了分段错误.

我有一个程序执行此操作:

用户插入char"s"
程序进入循环并将数组中的字符串保存(名称:cod).
当用户插入char"t"时,它会停止

之后我将该数组保存在新动态数组的第一个位置(名称:vec).

然后,如果用户再次插入char"s"
程序进入循环并将字符串保存在数组中.
当用户插入char"t"时,它会停止

之后我将该数组保存在新动态数组的第二个位置.

等等.


这是我的代码:

int main(){

char Cod[30][11];
char tmp[11];
char ***vec;
int i = 0;


strcpy (tmp, "p");

vec = (char *** ) malloc (sizeof ( char *) );
vec[0] = (char ** ) malloc (sizeof ( char *) * 30);


do {

    scanf("%s", tmp);

    while( (strcmp (tmp, "p")) != 0){

        strcpy ( Cod[i] , tmp ); 

        scanf("%s", tmp);

        i++;
    }

    vec = (char ***) realloc (vec, sizeof ( char *) * (i + 1));
    vec[i + 1] = (char ** ) realloc (vec[i + 1], sizeof ( char *) * (30));
    vec[i-1] = (char **) Cod;
    scanf("%s", tmp);

}

while((strcmp (tmp, "s")) == 0);

    printf("%s", vec[0][0]);
Run Code Online (Sandbox Code Playgroud)

返回0;

}

这是代码的一部分:

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


int main(){

    char Cod[30][11];
    char tmp[11];
    int i = 0;


    strcpy (tmp, "p");


    do {

        scanf("%s", tmp);

        while( (strcmp (tmp, "p")) != 0){

            strcpy ( Cod[i] , tmp ); 

            scanf("%s", tmp);

            i++;
        }

        scanf("%s", tmp);

    }

    while((strcmp (tmp, "s")) == 0);

        printf("%s", Cod[0]);

return 0;

}
Run Code Online (Sandbox Code Playgroud)

Lun*_*din 6

我开始修复这段代码,但很快意识到它有很多错误,我不知道从哪里开始.所以相反,这反过来是一个代码审查答案,如果它是详细和挑剔我道歉.

  • C中有一条经验法则,如果你需要两个以上的指针间接层,你的代码就会被混淆,应该重写(参考MISRA-C:2004 17.5).

  • 在这种情况下使用动态内存分配没有任何意义,因为在程序启动时你已经知道没有字符串将超过11个字符,并且不会有超过30个字符串.如果这种情况不成立,你需要编写一个更安全的输入方法,最好用fgets()来防止缓冲区溢出.确保输入不超出数组"Cod"的范围.您可以静态分配30*11 = 330个字节而不会有良心.它会使代码更快.

  • 对于字符串数组有3级间接是没有意义的.你甚至没有使用动态内存来保存字符串的副本,你只需要分配指针.这根本没有任何意义.如果需要指向的指针查找表Cod然后静态分配它,它只需要sizeof(char*)*30个字节.

  • 如前所述,您只能在以前使用malloc/calloc:ed的指针上使用realloc.

  • 如前所述,永远不要在C中使用malloc/realloc的结果进行类型转换.这是C++实践.在C中,它破坏了类型安全性并隐藏了类型兼容性错误.如果您想了解详细信息,可以在此处进行无数详细的讨论.

  • 如果在用户字符串中找不到"p"怎么办?该计划将受到严重破坏.

  • 不要将影响基本程序功能的变量命名为抽象的东西,如tmp,vec等.tmp可以重命名为input_buf或其他东西等.

  • 避免使用代码中的幻数,使用const或#define作为数组长度常量.

  • 您可以在C中初始化字符串,不需要strcpy来执行此操作. char input_buf[INP_BUF_N] = "p";

  • 要在字符串中搜索char,请使用strchr().

  • 您不应该让用户在外部do-while循环中使用scanf()两次输入相同的东西,这可能是一个错字错误.

  • 您不能在静态数组数组与指向指针之间进行疯狂的类型转换.这取决于指向指针的指针的结构.因为一个典型的哑学校书动态2D数组(malloc(X sizeof(char)... malloc(Y*sizeof(char))不会相邻地分配内存.在这里有关于此的大量讨论.

(您可以使用数组指针或"mangling"在相邻内存中分配动态2D数组,但这些是相当高级的主题)

  • free()动态内存一旦你完成使用它.

正如您希望的那样,这里明智的选择是从头开始重写此代码.