C - strcpy() 处的分段错误

C - Segmentation fault at strcpy()

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

char *vStrs[] = {"Max", "Moritz", "Bolte", "Hans Huckebein", "Helene", "Antonius", "Boeck", "Maecke", "Lempel", "Schlich"};

int main()
{
    int num = sizeof(vStrs) / sizeof(vStrs[0]);
    int len = sizeof(vStrs[0]);
    char exchnge[len];
    char vBuf[128];
    char *ndata;
    int i, j;

    for(i=0; i<num-1; i++)
    {
        for(j=i+1; j<num; j++)
        {
            if(strcmp(vStrs[j], vStrs[i]) < 0)
            {
                strcpy(exchnge, vStrs[j]);
                strcpy(vStrs[j], vStrs[i]);
                strcpy(vStrs[i], exchnge);
            }
        }
    }

    for(i=0; i<num; i++)
        printf("%s\n", vStrs[i]);

    return 0;
}

大家好,

有谁知道为什么我在第 strcpy(vStrs[j], vStrs[i]); 行遇到分段错误?

我有一个字符串数组,想对其进行排序。但是我遇到了分段错误。上面的 strcpy() 函数有效。怎么了?

可能很明显,但我不明白。

谢谢!

使用 strcpy(vStrs[j], vStrs[i]),您可以将一个字符串文字的内容复制到另一个字符串文字中。这就像你写 strcpy("Max","Moritz") 一样,但不能修改字符串文字(它的未定义行为)。

无论如何,您的程序的目的是交换 指向内容 的指针,而不是内容本身。所以如果你把程序改成下面这样,应该就OK了:

char *vStrs[] = {"Max", "Moritz", "Bolte", "Hans Huckebein", "Helene", "Antonius", "Boeck", "Maecke", "Lempel", "Schlich"};

int main()
{
    int num = sizeof(vStrs) / sizeof(vStrs[0]);

    for(int i=0; i<num-1; i++)
    {
        for(int j=i+1; j<num; j++)
        {
            if(strcmp(vStrs[j], vStrs[i]) < 0)
            {
                char *exchnge = vStrs[j];
                vStrs[j] = vStrs[i];
                vStrs[i] =exchnge;
            }
        }
    }

    for(int i=0; i<num; i++)
        printf("%s\n", vStrs[i]);

    return 0;
}

...因为您没有运行您的编译器可能处于最严格的错误检查模式。

有些人认为-Wall就是"all warnings"。它没有。甚至 -Wall -Wextra 都没有接近 "strictest error-checking mode possible"。我将从 -Wall -Wextra -pedantic -Wmissing-include-dirs -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wmissing-declarations -Wredundant-decls -Wshadow -Wno-system-headers -Wno-deprecated -Wunused-variable -Wunused-parameter -Wunused-function -Wunused 开始,然后参考 the manual 以了解您的编译器是否可以为您做更多事情。

如果您不使用 GCC,请根据您选择的编译器调整最后一段。编译器是你的朋友,尽可能给他机会,让你不犯错误。

启用这些选项后,您会收到以下警告:

warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]

因为这是发生的事情:就语言标准而言,"Max" 属于 char * 类型,但是——作为字符串文字——内存指向 不可写。这就是为什么您的 strcpy() 会在您的机器上出现段错误。使用 -Wwrite-strings,您告诉编译器改为生成字符串文字 char const *(就像它们在使用 C++ 时一样),使编译器能够在您忽略文字的不可写性质时生成警告。

编译器警告。不要没有他们就离开家。