【问题标题】:dynamic memory allocation for strings in cc中字符串的动态内存分配
【发布时间】:2013-10-09 04:49:18
【问题描述】:

我发现这段代码运行良好。

#include <stdio.h>
#include <stdlib.h>




int main(int argc,char *argv[])
{
    char* s;        /* input string */
    s=malloc(sizeof(s));    

    int c;

    if(argc==1){ // if file name not given


        while (gets(s)){
            puts(s);
        }
    }
}

我不明白的是,字符串s是如何存储在内存中的。我只为指针s分配内存,它有4个字节。现在用户给出的输入字符串存储在哪里?

【问题讨论】:

  • 澄清一点:如果您在 main 中声明 schar* s; 一样,您不会使用 malloc 分配内存来存储该变量。该变量的内存将在堆栈上并且已经为您“分配”。对malloc 的调用决定了您在该变量中存储的什么,而不是您存储该变量的何处
  • 是的。现在我明白你的意思了。谢谢

标签: c string memory


【解决方案1】:

只有前四个字节是安全的。第五个字节将超出分配的数据并踩踏其他会产生未定义行为的东西(可能会崩溃,也可能不会)。

此外,在完成字符写入后,您不会使用 '\0' 终止字符串,因此当您尝试对其调用字符串例程 (strcpy) 时,您可能会引入另一个崩溃 - 除非内存在你的字符串碰巧包含零之后,但自然你不应该依赖这个机会!

【讨论】:

  • 好的。但是当我们尝试使用分配给其他进程的内存部分时,我们不应该总是得到像分段错误这样的错误吗?
  • 它不一定分配给另一个进程。它可能是属于您的流程的另一个变量。 C 不会对每个操作执行边界检查,因为这样做会在性能方面产生成本。
  • 是的。或者当您超出为您的进程分配的内存页面时。它仍然很远,因此仅仅用户输入的字符串可能还远远不够。 gets() 用零字节终止字符串。
【解决方案2】:

你应该这样做而不是这样做

s=malloc(sizeof(*s)*(number_of_chars+1)); 

您将number_of_chars 设置为适当的值,以便分配内存来存储这些字符。 +1 是最后一个 '\0' 字符。

通过您的方法,您分配了4 bytes,因此您通常可以存储那么多字符。

【讨论】:

  • 好的,我明白你的意思。但是我的代码是如何工作的?这就是我感到困惑的地方
  • @DesirePRG,通过您的方法,您分配了 4 个字节,因此您通常可以存储这么多字符。
【解决方案3】:

您已分配 sizeof(void*) 字节的内存并用用户提供的数据填充它。你有一个地址并写入它,从编译器的角度来看是可以的(也许这真的是你想要的,谁知道呢)。即使你的程序在超过它时没有崩溃——它仍然是一个错误。它只是一个记忆,其他东西可以存储在这个区域,你会覆盖它 - 所以如果你这样做的话,预计会有很大的麻烦。

【讨论】:

    【解决方案4】:

    编译器分配两个字节是可能的。 现在您在输入中提供 10 个字节,因此您分配的内存会溢出,并且只有在可用时才存储超出分配的内存的数据。

    如果您要存储的数据大于可用数据,则可能会出错,如果您要存储的数据大于已分配的数据,则不会出错。

    puts 将打印数据,直到它得到 '\0'。

    所以这是预期的行为!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 2016-08-04
      • 2016-09-29
      相关资源
      最近更新 更多