【问题标题】:Dynamic memory allocation code动态内存分配代码
【发布时间】:2016-01-02 16:29:38
【问题描述】:

我正在学习 C(C++) 中内存分配的基础知识。

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
void main(){

    char *str;
    char *input;
    int *ilist;
    int i, size1, size2;

    printf("Number of letters in word: ");
    scanf("%d", &size1);
    printf("Number of integers: ");
    scanf("%d", &size2);                  

    str = (char *)malloc(size1*sizeof(char) + 1); 

    ilist = (int *)malloc(size2*sizeof(int)); 
    if (str == NULL || ilist == NULL){ 
        printf("Lack of memory");
    }
    printf("Word: ");
    int k = size1;
    // the following line is done to prevent memory bugs when the amount of 
    letters in greater than size1.
    scanf("%ks", &str); //I guess something is wrong with this line
    /* user inputs a string */
    for (i = 0; i < size2; i++) {
        printf("Number %d of %d: ", i + 1, size2);
        //this scanf is skipped during the execution of the program
        scanf("%d", ilist + i);         
    }


    free(str);
    free(ilist);
    system("pause");

}

程序要求用户写出单词中字母的数量和数字中的位数。然后用户写这个词。然后他根据之前输入的数字一个接一个地写入整数。我遇到的问题是当用户写下整个单词时,会跳过下一个 scanf。 谢谢你。 附:此代码中是否还有其他类型的内存错误?

【问题讨论】:

  • 检查scanf的返回值是个好主意。
  • 第一课 c != c++ 并且在 c 中您不需要将 malloc() 转换为目标指针类型,因为您不需要。
  • 我建议安装 Valgrind valgrind.org 来检查内存泄漏。
  • @EdHeal;否。从 C99 开始,返回类型应为 int
  • @EdHeal:对于托管环境/它是 UB,根据 C11 标准附录 J2 以及 5.1.2.2.1。

标签: c dynamic-memory-allocation


【解决方案1】:

关于//我猜这行有问题...
scanf("%ks", &amp;str); 中的格式说明符 "%ks" 包含一个 k,它不是有效的 scanf() format specifier

摘自链接:

对于width 说明符中的用户输入值,您可以创建格式缓冲区:

char format[10];
int k = size1;//assume size1 == 10
sprintf(format, "%c%d%c", '%', k, 's');
//assuming k == 10, format contains "%10s"
scanf(format, &str); //now, there is nothing wrong with this line

其他观察
several recommended prototypes for the C main functionvoid main() 不是其中之一。

这一行str = (char *)malloc(size1*sizeof(char) + 1);
可以写成:

str = malloc(size1 + 1); //removed sizeof(char) as it is always 1
                         //removed cast, not recommended in C

类似ilist = (int *)malloc(size2*sizeof(int));

ilist = malloc(size2*sizeof(int));//remove cast, but keep sizeof(int) 
                                  //unlike sizeof(char), sizeof(int) is never 1 

在 C 中考虑动态内存分配的一些基础

1) 在 C 中,不要转换 calloc(), malloc() or realloc() 的输出。 (但是,请使用 C++ 进行转换。)
2) 每次调用calloc()、malloc()或realloc(),都必须有对应的调用free()
3) 虽然自动内存来自 stack,但动态内存来自 heap
4) 如果speed efficiency is important,优先选择堆栈而不是堆。

【讨论】:

    【解决方案2】:

    不要使用scanf,而是使用fgets。但是,您需要先清除输入缓冲区以消耗之前的scanfs 留下的\n

    int c;
    while((c = getchar()) != '\n' && c != EOF); // Clear input buffer  
    fgets(str, k, stdin);  
    

    请注意,如果读取了'\n',那么它将存储在str 中。你应该注意这一点。

    【讨论】:

    • @BasileStarynkevitch;不是标准的 C 库函数。
    • @hacks:但它是 POSIX。
    猜你喜欢
    • 2011-09-16
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 2013-07-01
    相关资源
    最近更新 更多