简体   繁体   English

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;
}

Hey guys,大家好,

does anyone know why I get a segmentation fault at line strcpy(vStrs[j], vStrs[i]);有谁知道为什么我在strcpy(vStrs[j], vStrs[i]);行出现分段错误strcpy(vStrs[j], vStrs[i]); ? ?

I have an array of strings and want to sort it.我有一个字符串数组,想对其进行排序。 But I get a segmentation fault.但是我遇到了分段错误。 The strcpy()-function above that works.上面的 strcpy() 函数有效。 What is wrong?怎么了?

Probably it's obvious but I don't get it.可能很明显,但我不明白。

Thankyou!谢谢!

With strcpy(vStrs[j], vStrs[i]) , you copy the content of a string literal into another string literal.使用strcpy(vStrs[j], vStrs[i]) ,您可以将字符串文字的内容复制到另一个字符串文字中。 This is just as if you wrote strcpy("Max","Moritz") , yet string literals must not be modified (its undefined behaviour).这就像你写了strcpy("Max","Moritz") ,但字符串文字不能被修改(它的未定义行为)。

Anyway, the intent of your program is exchanging pointers to contents , not the contents per se.无论如何,您的程序的意图是交换指向内容的指针,而不是内容本身。 So if you change the program as follows, everything should be 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;
}

...because you did not run your compiler in the strictest error-checking mode possible. ...因为您没有以最严格的错误检查模式运行编译器。

Some people believe that -Wall means "all warnings".有些人认为-Wall意思是“所有警告”。 It doesn't.它没有。 Not even -Wall -Wextra even comes close to "strictest error-checking mode possible".甚至-Wall -Wextra甚至都无法接近“可能的最严格的错误检查模式”。 I would start with -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 , and then refer to the manual to find if there is more your compiler can do for you.我会从-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 ,然后参考手册查找您的编译器是否可以为您做更多。

Adapt that last paragraph to your compiler of choice if you aren't using GCC.如果您不使用 GCC,请根据您选择的编译器调整最后一段。 The compiler is your friend, give him every chance possible to keep you from making mistakes.编译器是你的朋友,给他一切可能的机会来防止你犯错误。

With those options enabled, you would get the following warning:启用这些选项后,您将收到以下警告:

warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]警告:初始化从指针目标类型 [-Wdiscarded-qualifiers] 中丢弃“const”限定符

Because this is what happens: "Max" is of type char * as far as the language standard is concerned, but -- as a string literal -- the memory pointed to is non-writeable .因为这是发生的事情:就语言标准而言, "Max"char *类型,但是 - 作为字符串文字 - 指向的内存是 non-writeable That is why your strcpy() segfaults on your machine.这就是为什么您的机器上的strcpy()原因。 With -Wwrite-strings , you tell the compiler to instead make string literals char const * (like they are when using C++), enabling the compiler to generate a warning when you ignore the non-writeable nature of the literal.使用-Wwrite-strings ,您可以告诉编译器将字符串文字改为char const * (就像使用 C++ 时那样),从而使编译器能够在您忽略文字的不可写性质时生成警告。

Compiler warnings.编译器警告。 Don't leave home without them.没有他们,不要离开家。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM