将内存分配给具有精确字符长度的指针

时间:2014-01-10 20:12:43

标签: c pointers memory-management

我是c的新手并且学习指针,我知道的是指针指向它所指向的内存地址。

我的问题是你如何分配内存的字符长度,或者需要50个字节?

让我们说他们进入了一个标题:饥饿游戏

BOOL AddNewDVD(Database* data){

}

3 个答案:

答案 0 :(得分:3)

  

我是c新手和学习指针

指针对初学者来说很难。确保你有一个坚实的基础。

  

目前我所知道的是指针指向它所指向的内存地址。

虽然这在实践中是正确的,但这并不是我想要的。您所描述的是指针通常是如何实现,而不是概念。通过将实现与概念混淆,您可以在以后编写错误的代码,从而做出无根据的假设。不要求指针是一个数字,它是虚拟内存系统中的地址。

考虑指针的更好方法不是作为地址,而是:

  • 指向t的指针是一个值。
  • *运算符应用于指向t的指针,为您提供类型为t的变量。
  • &运算符应用于t类型的变量会为您提供指向t。
  • 的指针
  • 类型为t的变量可以获取或存储类型为t的值。
  • 数组是一组变量,每个变量都由索引标识。
  • 如果指针引用了与数组中索引i关联的变量,则p + x会为您提供一个引用与索引i + x关联的变量的指针。
  • [i]运算符应用于指针是*(p+i)
  • 的简写

也就是说,不要将指针视为指向内存中某个位置的数字,而只需将其视为可以强制为您提供变量的内容。

  

这是你如何准确分配内存的扫描字符串的长度,或者它需要50个字节?

 char *title = malloc(50 * sizeof(char));
 scanf(" %[^\n]s", title);

malloc(50*sizeof(char))为您提供50个字符数组。

title是指向char的指针。

取消引用后,title会为您提供与数组中第一项关联的变量。 (项目零;请记住,索引是距离第一个项目的距离,并且第一个项目与第一个项目的距离为零。)

scanf将用户输入的字符填入50个字符的数组中。

如果他们输入超过49个字符(记住按惯例放在最后会有一个零字符),那么就会发生任意不好的事情。

正如您所正确注意的那样,要么浪费了大量空间,要么可能会溢出缓冲区。解决方案是:不要将scanf用于任何生产代码。这太危险了。而是使用fgets。有关详细信息,请参阅此问题:

How to use sscanf correctly and safely

答案 1 :(得分:0)

您需要有一个缓冲区才能知道输入的名称有多长。这是你的title,最多可以填充49个字符。然后你计算len,看它只有6个字节长。您将string分配为此大小+ 1。

当然,您可以将title的内容写入string,即使title是50字节长的缓冲区,string只有7字节长 - 复制内容以\0终止字符结尾,并且保证在string的容量范围内。

答案 2 :(得分:0)

您无法使用scanf来确定字符串的长度,然后为其分配内存。你需要:

  1. 询问用户字符串的长度。显然,这是一个糟糕的选择。
  2. 创建一个足够大的静态缓冲区,然后创建一个所需长度的动态字符串。问题是,确定字符串的最大长度。 fgets可能就是您所需要的。请考虑以下代码片段:

    #define MAX_STR_LEN (50)
    
    char buf[MAX_STR_LEN] = {0};
    char *str, *cPtr;
    
    /* Get User Input */
    printf("Enter a string, no longer than %d characters: ", MAX_STR_LEN);
    fgets(buf, MAX_STR_LEN, stdin);
    
    /* Remove Newline Character If Present */
    cPtr = strstr(buf, "\n");
    if(cPtr)
        *cPtr = '\0';
    
    /* Allocate Memory For Exact Length Of String */
    str = malloc(strlen(buf) + 1);
    strncpy(str, buf, strlen(buf));
    
    /* Display Result */
    printf("Your string is \"%s\"\n", str);