【问题标题】:Why does scanf and malloc to char pointer work even if the size is not specified?为什么即使未指定大小,scanf 和 malloc to char 指针也能工作?
【发布时间】:2012-10-12 23:25:34
【问题描述】:

我正在刷新我的 C 技能。我正在使用 char *s 并使用 malloc 为 s 分配内存。然后使用scanf,我将输入读取到s。但我的问题是我没有指定内存块的大小。但该程序有效。如何为任意长度的输入字符串分配内存? scanf 是否只是增加指针并将数据写入该位置?

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

int main() {
    char *s;
    s = (char *) malloc(sizeof(s));    //I did not specify how much like malloc(sizeof(s) * 128)
    if (s == NULL) {
        fprintf(stderr, "\nError allocating memory for string");
        exit(1);
    }
    scanf("%s", s);
    puts(s);
    free(s);
    return 0;
}

/*
    Input:
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    Output:
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
*/

【问题讨论】:

  • 您正在调用未定义的行为。你现在可以侥幸逃脱,但这是一场等待发生的灾难。

标签: c string pointers malloc


【解决方案1】:

您只分配大小等于Integer 的内存。如果你向这个变量写入更长的字符串,它只会覆盖现有的内存位置,而且你的程序会出现意外的行为。

【讨论】:

  • 1) C 中没有Integer,只有int; 2)sizeof(s) == sizeof(char *),可能不等于sizeof(int)
  • sizeof(s) == sizeof(char *)。指向字符的指针不是地址吗?地址是如何存储的?不作为整数?可能会很长?
【解决方案2】:

sizeof(s) 是否返回字符指针的大小,取决于您是在 32 位还是 64 位平台上运行,它将为 4 或 8 个字节。

您想改用sizeof(*s)。但是,由于 C 标准指定 sizeof(char)(即 sizeof(*s) 将是)为一,因此对于字符数组,您不需要它。

【讨论】:

  • 感谢sizeof(*s) 而不是sizeof(s) 的提示。
【解决方案3】:

您确实指定了大小:sizeof(s)。因为schar *sizeof(s) == sizeof(char *)。根据您的平台,这可能是 4 或 8 个字节的长度。

因此,您有效地分配了 4(或 8)个字节来存储字符串。如果您在命令行上键入超过 3(或 7)个字符,那么您将开始写入超过分配数组的末尾,这会触发 未定义的行为。对于未定义的行为,任何事情都可能发生:您的程序可能看起来工作正常,程序可能会用 ZALGO 填充其余内存,程序可能会出现可怕的段错误,或者您可能会遇到流行的鼻恶魔。 C 规范没有具体说明会发生什么(因此称为“未定义行为”)。

您的程序“有效”的事实完全是侥幸,不应依赖

【讨论】:

    【解决方案4】:

    对于char *s;sizeof(s)sizeof(char *) 相同,为 4 或 8,具体取决于您使用的是 32 位盒还是 64 位盒。

    如果您使用的是 32 位框,那么您可以存储 3 个字符以及空的“字符串结尾”字符。如果你存储更多它可能爆炸。

    【讨论】:

    • 但它并没有爆炸。查看输入和输出。
    • @kadaj:这是未定义的行为。也许它可以工作,也许明天它不工作,也许你把它放在朋友的电脑上,它会点亮 CPU。您不能也不应该依赖这种工作方式。
    【解决方案5】:

    它只会allocate the space =size of char * 而不是 只是增加指针并将数据写入该位置?如你所想。

    为什么它起作用的答案是:因为它把它写在没有分配给你的内存区域上,但是如果该区域被其他进程保留,你的程序就会崩溃。所以最好分配更大的空间。

    【讨论】:

    • 现代操作系统都不会让您使用这种方法写入“其他进程”的内存空间。内存被虚拟寻址。您可能正在编写自己流程中不应该的其他领域。
    【解决方案6】:

    sizeof(s) 返回s 的大小(以字节为单位),其类型为char*。通常在 32 但机器上这是 4 字节和 64 位机器上的 8 字节。所以你实际上已经告诉 malloc 要分配的字节数,s 将指向该内存区域。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      相关资源
      最近更新 更多