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++ 时一样),使编译器能够在您忽略文字的不可写性质时生成警告。
编译器警告。不要没有他们就离开家。
#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++ 时一样),使编译器能够在您忽略文字的不可写性质时生成警告。
编译器警告。不要没有他们就离开家。