C 中字符串的内存分配

问题描述 投票:0回答:1

我在 C 中尝试了这种方法,因为我不想预定义 char* 的大小(如 char[999]),我的主要目的是创建一个 char* 变量来保存特定的单词(我不知道它是如何运行的)当我使用这段代码时(我也不相信它会在我编码时正常工作),它会为一个字符创建一个内存空间。但是当我尝试打印时,它会打印整个字符串,令人惊讶的是,当我调试它时控制台只显示字符串的第一个字符

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


struct Node
{
    int val;
    char* name;
    struct Node* next;
};

int main()
{
    struct Node* list;
    list=(struct Node*) malloc(sizeof(struct Node));
    list->name=(char*) malloc(sizeof(char));
    printf("Enter a string");
    scanf("%s",list->name);
    printf("%s",list->name);
    return 0;
}

我认为存在内存泄漏或其他问题。因为 malloc() 函数中没有任何乘数,我不相信编译器会分配足够的内存,但我不知道它如何保存第一个我不知道在哪里的字母之后。

c memory
1个回答
0
投票

当您使用 malloc(sizeof(char)) 为 name 分配内存时,您正好分配了一个字节的内存,这足以容纳一个字符。在 C 中,字符串以 null 结尾,这意味着它们以特殊的 null 字符 (' ') 结尾。因此,从技术上讲,这个分配只有空字符串的空间(只是空终止符)。

当您使用 scanf("%s", list->name) 从用户读取字符串时,scanf 并不知道您只为一个字符分配了空间。它将继续将用户的输入写入从 list->name 开始的内存中,如果用户输入多个字符,则可能会超出分配的空间。这称为缓冲区溢出,是 C 程序中错误和安全漏洞的常见来源。

尽管存在缓冲区溢出,您可能会发现您的程序对于小字符串似乎可以正常工作。这是因为写入超过分配的内存可能不会立即导致崩溃;它会覆盖程序内存的其他部分,这些部分可能不会立即使用或检查。然而,这是不可预测且不安全的。该行为可能会随着不同的输入、编译器优化甚至同一程序的不同运行而改变。

如前所述:“因为我不想预定义 char* 的大小(如 char[999]),我的主要目的是创建一个 char* 变量来保存特定单词”

也许你可以这样写:

char buffer[999];
int main()
{
    scanf("%s", buffer);
    int len = strlen(buffer);
    printf("%d", strlen(buffer));

    struct Node* list;
    list = (struct Node*)malloc(sizeof(struct Node));
    list->name = (char*)malloc((len + 1) * sizeof(char));
    strcpy(list->name, buffer);
    printf("%s", list->name);
    return 0;
}

我认为不可能提前预测用户会输入多少个字符......

© www.soinside.com 2019 - 2024. All rights reserved.