内存故障和指向字符串的指针

问题描述:

所以我试图扭转一个字符串,但我得到一个内存故障。 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); 
} 
+1

你认为'* s = * s1'和's = s1'之间的区别是什么? –

+0

前者取值s1指向并将其放在地址s中指向,而后者指向s1指向 – CodeChef123

+0

@ScottHunter:好的,我明白了为什么应该起作用。但是* s1 * s1 – CodeChef123

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

+0

好的,所以实际上* s = * s1只会替换第一个字符?不是整个字符串? – CodeChef123

+0

@ CodeChef123没错。如果's'不是一个字符串文字并且可以修改,你应该已经完成​​了's = s1'。并且不要忘记用'free(s1)''释放's1'的内存。 –

+0

所以你说地址是指向在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; 
} 

在使用后释放内存是一种很好的做法。