内存故障和指向字符串的指针
所以我试图扭转一个字符串,但我得到一个内存故障。 s和s1的存储器初始化足以容纳'/ 0'字符。内存故障和指向字符串的指针
有趣的是,如果我删除* s = * s1并打印s1而不是程序工作。 但是我甚至没有在s1的末尾设置“\ 0”字符,所以它甚至不知道在哪里停止打印?
而在下面的情况下究竟是什么问题?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main(void)
{
char *s = "abcdefghijklmnop", *s1=malloc(17);
int i;
for(i=0;i<strlen(s);i++)
{
*(s1+i) = *(s+strlen(s)-1-i);
}
*s=*s1;
printf("%s",s);
}
char *s = "abcdefghijklmnop"
是一个字符串文字,它通常在只读存储器中。 如果您尝试修改字符串文字,则会生成错误。
当您执行*s=*s+1
时,您试图将s
中的第一个字符替换为s1
中的第一个字符。
如果s
不是字符串文字,则应该执行s=s1
而不是*s=*s1
,以使s
反转。
更多关于这一点:
https://softwareengineering.stackexchange.com/questions/294748/why-are-c-string-literals-read-only
String literals: Where do they go?
where in memory are string literals ? stack/heap?
正确的串印有printf("%s", s1);
即使没有\0
储存,因为内存旁边正好是0
的最后一个字符,其相当于\0
。这并不总是如此,并且不能被依赖,因为malloc()
不初始化它分配的内存。
但calloc()
将初始化它分配给0
的内存。
查看更多here。
好的,所以实际上* s = * s1只会替换第一个字符?不是整个字符串? – CodeChef123
@ CodeChef123没错。如果's'不是一个字符串文字并且可以修改,你应该已经完成了's = s1'。并且不要忘记用'free(s1)''释放's1'的内存。 –
所以你说地址是指向在ROM?是否有任何理由,因为它似乎更像一个正常的指针(* ints,例如) – CodeChef123
在您的代码*s=*s1
中,只将s1的第一个内容复制到s中。即*(s+0)=*(s1+0)
不是整个字符串。所以我们需要将s1的地址分配给s。即,s=s1
。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *s = "abcdefghijklmnop", *s1=malloc(17);
int i;
for(i=0;i<strlen(s);i++)
{
*(s1+i) = *(s+strlen(s)-1-i);
}
s=s1;
printf("%s",s);
free(s1);
return 0;
}
在使用后释放内存是一种很好的做法。
你认为'* s = * s1'和's = s1'之间的区别是什么? –
前者取值s1指向并将其放在地址s中指向,而后者指向s1指向 – CodeChef123
@ScottHunter:好的,我明白了为什么应该起作用。但是* s1 * s1 – CodeChef123