#include<stdio.h>
#include<string.h>
int main()
{
void sort(char * name[],int n);
char * name[]={"Follow me","Basic","Great Wall","FORTRAN","Computer Design"};
int i,n=5;
sort(name,n);
for(i=0;i<n;i++)
printf("%s\n",name[i]);
return 0;
}
void sort(char * name[],int n)
{
int i,j,k;
char *temp;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(strcmp(name[k],name[j])>0)
k=j;
if(i!=k)
{
temp=name[i];
name[i]=name[k];
name[k]=temp;
}
}
}
书上说,不用字符串数组而用字符串指针的原因是字符串长度不一,使用 数组必须制定
长度会造成内存浪费.比如有的字符串的长度次是6,8,20,22,25. 我对它的理解是那如果
用字符串数组就必须指定列长度为25,则第一个字符串有很多空值,造成浪费,那字符数组
则是在第一个字符串之后马上存储第二个字符串,它们应存储在连续的内存空间,才节省内存
但事实相反,用字符串指针在内存中也有很多空值,如下图所示,求解惑
#include<string.h>
void sort(char *p[5]);
int main()
{
char ** str = (char **)malloc(20);
str[0] = (char *)&"Follow me";
str[1] = (char *)&"Basic";
str[2] = (char *)&"Great Wall";
str[3] = (char *)&"FORTRAN";
str[4] = (char *)&"Computer Design";
sort(str);
for (int i = 0; i < 5; i++)
{
printf("%s\n", str[i]);
}
}
void sort(char *p[5])
{
int i,j,k;
char * temp = 0;
for(i=0;i<5;i++)
{
k=i;
for(j=i+1;j<5;j++)
if(strcmp(p[i],p[j])>0)
k=j;
if(i!=k)
{
temp = p[i];
p[i] = p[k];
p[k] = temp;
}
}
}
解决此类问题:0xC0000005:Acess Vilation ,最好的是方法是调试,不是看汇编代码。
str 都是指向常量的,还样它的值是不能修改的。试图修改即报 Acess Vilation 的错误。
就像定义一个指针,char *p = "p提向常量型字符串,此字符串是存贮在常量区";
接下来,试图对 p[0] 及其它 p 下标的数值进行修改,都会直接引起异常。
你的代码,只不过将问题在指针变成了指针数组,但实质还是一样的。
需要用new或者malloc分配内存,在堆上存放字符串数组。
运行结果
Computer Design
Basic
Follow me
FORTRAN
Great Wall
没看到你修改过的代码,请你贴在codepad.org上,把链接贴在这里
char * str[]={"Follow me","Basic","Great Wall","FORTRAN","Computer Design"};
这个字符串数组的字符串都存储在了常量区(rdata段,是只读的内存区域),因此在做
strcpy(p[i],p[k]);
strcpy(p[k],temp);
的时候就会发生访问违例(Access Violation)。
事实上,str是一个指向字符串首地址的指针的数组,而这些指针指向的是只读的内存,因为这些字符串存储在了只读的内存。
你这个程序中应该使用
char str[][16] = {"Follow me","Basic","Great Wall","FORTRAN","Computer Design"};
一是因为这样编译器不会把字符串存在常量区,二是每个字符串都有足够的位置来容纳其他字符串,在做
strcpy(p[i],p[k]);
strcpy(p[k],temp);
的时候不会把 原字符串 以外的位置都覆盖掉(例如strcpy(str[0], str[4])可能会把"Follow me"之后的"Basic"覆盖掉。
0xC0000005:Access Violation
一般是触发了Intel、AMD架构的分段(segmentation)保护机制,例如程序访问没分配给它的内存(一般因为null指针),或者像你的这段程序那样意图写入只读的内存区域。
要想深入了解这个错误发生的原因,你需要去了解程序的代码段(code段或text段)、一般数据段(data段)、未初始化数据段(bss段)、常量数据段(rdata段)等的作用及区别。
用字符串指针在内存中也有很多空值是因为编译器为了调试的需要或者给不安全的strcpy(像你的程序中的strcpy)留有缓冲的空间。或者,最主要的原因是编译器想做内存对齐优化。
你可以发现,每个字符串所占的空间都是4字节的倍数。做了内存对齐优化,可以减少CPU访问缓存的不命中率和减少CPU访问内存的次数。要想深入了解的话请找计算机原理的书看。
以后不要这么做。
应该保留原来的代码。因为之前的回答是针对之前你的代码来的。你修改了问题,会让以后阅读到这个帖子和你有类似问题的人不知所以然。