修改Cstring常量?

可能重复:
为什么在写入string时会出现分段错误?

我想写一个函数,反转给定的string传递给它。 但是我不能。 如果我用字符数组提供doReverse函数(见下面的代码),我的代码运行良好。

我不明白为什么这不起作用。 我能够访问doReverse str[0] ,但我不能通过使用char指针来更改数组的任何值。 有任何想法吗?

 void doReverse(char *str) { str[0] = 'b'; } void main(void) { char *str = "abc"; doReverse(str); puts(str); } 

更新:

我知道如何通过传递一个字符数组来写一个反向函数:

 void reverse1(char p[]) { int i, temp, y; for (i = 0, y = strlen(p); i < y; ++i, --y) { temp = p[y-1]; p[y-1] = p[i]; p[i] = temp; } } 

但是,我想编写另一个获取char指针作为参数的版本。

最简单的解决方法是将str的声明更改为

 char str[] = "abc"; 

这使得str被初始化为string“abc”的char数组。 目前,你已经将str指向char初始化为指向由string文字描述的string。 有一个关键的区别:string文字是只读的,使编译器在存储它们的地方有最大的灵活性; UB修改它们。 但char数组是可变的,所以可以修改它们。

PS。 main()返回一个int

既然你正在学习考试,我会充实一下我的评论来解释实际发生的事情:

 char *str = "abc"; 

str是存储在堆栈上的一个指针。 它被初始化为指向string"abc" 。 该string将被存储在编译的可执行文件的数据部分中,并在加载程序时被加载到内存中。 这部分内存是只读的,因此当您尝试修改str所指向的数据时,会出现访问冲突。

 char* str = malloc(sizeof(char) * 4); strcpy(str, "abc"); 

在这里,str和第一个例子是一样的堆栈指针。 这一次,它被初始化为指向堆上可以读取和写入的4个字符的内存块。 起初,这块内存是未初始化的,可以包含任何东西。 strcpy读取存储“abc”的只读存储器块,并将其复制到str指向的读写存储器块中。 请注意,设置str[3] = '\0'是多余的,因为strcpy已经这样做了。

顺便说一句,如果你在Visual Studio中工作,而是使用strcpy_s,而不是覆盖你的缓冲区,如果被复制的string比你想象的要长。

 char str[] = "abc"; 

这里str是现在在堆栈上分配的数组。 编译器会根据用来初始化它的string(包括NULL终止符)来确定它的大小。 堆栈内存是可读写的,因此您可以根据需要修改数组中的值。

 char str[4] = "abc"; 

这与以前的版本实际上是一样的,只有你告诉编译器,你知道的比数组应该是多长。 如果更改string而不是数组大小,可能会遇到麻烦。

因为这是作业,我会提供build议,但我不会发布一个完整的解决scheme。

我猜你正在越来越访问冲突str [0] ='b'? 这是因为“abc”是一个string文字。

在调用reverse之前将str的string复制到指定的位置,或者反过来分配一个缓冲区,并将反转的string放入该位置。

请记住,您将不得不释放所有分配的内存。

嘿,陛下。 对于所有build议实际进行交stream的人,请仔细阅读这个问题。 没有什么比不得不重申一个已经完美expression的问题更糟了。 不pipe用什么方法来实现交换(temp-swap,xor3-swap等),这个人似乎对函数的基本内涵和相当基本的内在知识都非常熟悉。

然而,正如已经解释的那样,编译器/链接器通常将所有string文字放置在目标可执行文件的“常数数据段”内,随后在适当的“加载/执行”调用期间将其与不可写MMU描述符相关联。 随后通过这个描述符发出的所有CPU写周期都被MMU的exception机制自动捕获,导致强制性的“段错误”或平台特定的等价物。 当然,老式的非MMU平台当然不会performance出这样的行为。

尽pipe这有效地促进了对源语言的“常量/文字”习语的运行时支持,但是有些平台在历史上已经促成了明确的编译时段覆盖。 但是,这种支持水平已经逐渐减less,变成了一个更加僵化和强大的抽象层,从而导致许多明显且常常有用的优化不成立。 随着时间和磨蚀在“微软”这一代人之前产生稳定老化的“MC / ASM”理念,程序员不再被认为是知识丰富或者负责任的人,而是做出这样的决定。 代替我曾亲眼目睹的项目负责人,而不是创造性的实现,这绝不是一件坏事。

虽然这篇文章正在迅速演变成一个脱离主题的侵权行为,但我感到有些自相矛盾的自上而下的相关问题在我们这个行业慢慢stream行起来。 作为一个刚起步的C语言程序员,我的build议是采用自下而上的方法,并用一些课外汇编语言开发来增强你的学习。 由于algorithm的实现可能会成为您作为应用工程师的主要关注点,所以要记住,当代CPUdevise在过去的30年中经历了一个统一的演变。 如今的超高速英特尔CPU不过是我在编程时的地球还年轻的4/8-bit双极性处理器的超标量CMOS改进。

与stream行的观点相反,汇编语言编程相对容易学习,而且当试图将高层次结构与有问题的或深奥的行为相协调时,绝对是必不可less的。 一旦你在实验,debugging,networkingsearch和论坛垃圾邮件的无休止的时间,无疑,自下而上的方法当然是阻力最小的path。

祝你学习好。

据我所知,常量string被实现为常量字符数组(或者,用C语言, const char [length] )。 因此,您不能修改其字符。

尝试dynamic分配string。

 char* str = (char*)malloc(sizeof(char) * 4); strcpy(str, "abc"); str[3] = '\0'; 

当然,不要忘记在程序结束时释放内存。


编辑:我不会发布任何有关扭转string,因为这是你的工作。