【问题标题】:Memory fault and pointer to string内存故障和指向字符串的指针
【发布时间】:2018-03-10 04:10:12
【问题描述】:

所以我试图反转一个字符串,但我遇到了内存错误。 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);
}

【问题讨论】:

  • 你觉得*s = *s1s = s1的区别是什么?
  • 前者把s1指向的值放到s指向的地址里,后者把s指向s1指向的地址
  • @ScottHunter:好的,我明白为什么应该这样了。但是 *s = *s1 有什么问题
  • 您无法写入与 *s 关联的内存。
  • 每当您想为某个指针p 和索引i*(p + i) 时,只需写p[i]。它更容易阅读,并且含义完全相同。

标签: c string pointers memory malloc


【解决方案1】:

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?

即使没有存储\0,也会使用printf("%s", s1); 打印正确的字符串,因为最后一个字符旁边的内存恰好是0,相当于\0。这并不总是如此,并且不能被依赖,因为malloc() 不会初始化它分配的内存。

但是calloc()初始化它分配给0的内存。

查看更多here

【讨论】:

  • 好的,所以实际上 *s = *s1 只替换第一个字符?不是整个字符串?
  • @CodeChef123 没错。如果s 不是字符串文字并且可以修改,那么您应该完成s=s1。并且不要忘记使用free(s1)s1 释放内存。
  • 所以你是说s指向的地址在ROM中?这有什么理由吗,因为它看起来像一个普通的指针(例如*ints)似乎更合乎逻辑
  • 对于我的问题的第二部分,如果我删除 *s=*s1 并打印 s1,程序如何知道何时停止打印,因为我没有提供 \0 字符
  • 关于第一部分,请参阅我刚刚添加的答案中的链接。关于第二部分,与最后一个字符相邻的内存可能恰好是0,相当于\0表示字符串的结尾。您不能依赖它,因为malloc() 不会初始化它分配的内存。但是calloc() 会用0 初始化它的内存。
【解决方案2】:

在您的代码*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;
}

最好在使用后释放内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 2013-04-26
    • 2020-03-23
    • 2011-12-03
    • 1970-01-01
    • 2011-04-12
    相关资源
    最近更新 更多