【问题标题】:reading string of unknown size读取未知大小的字符串
【发布时间】:2017-02-10 10:08:18
【问题描述】:

我写了这个函数,它逐个字符地读取字符串并增加分配的大小。 由于某种原因,我在 VS2010 中随机出现错误“_CrtIsValidHeapPointer”,同时读取大约 100+ 个字符的字符串。 我试图调试它,但我真的不知道什么是错的

char *unknown_size_string(){
    int i=0, size=10;
    char *name=NULL, *alloc_check=NULL, letter;
    //allocates initial size of 10 bytes
    name=(char *)malloc(sizeof(char)*size);
    if(!name){return NULL;}
    //reads char by char until newline reached
    while((letter=getchar())!='\n'){
        *((name)+i++)=letter;
        //when the remaining buffer size is 1 byte, allocating another 10 bytes
        if((i+1)==size){
            alloc_check=name;
            realloc(alloc_check,(size+=10)*sizeof(char));
            if(!alloc_check){return name;}
            name=alloc_check;
        }
    }
    *((name)+i)='\0';
    return name;
}

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 最后一个*((name)+i='\0'; 可能会导致错误,如果字符串的确切长度为 10 个字符,您将不会重新分配它,然后在第十一个位置添加 '\0' (i = 10).. . 或者我错了
  • 我想我在剩下 1 个字节时已经被分配覆盖了,但我想看看它是否改变了什么
  • @MartinVerjans 你是对的。检查应考虑结束空空间。
  • 应该没有剩余字节,因为寻址从第 0 个元素开始(当您检查 i+1,i=9 时,您刚刚分配了第 10 个元素)。
  • 您可能对getline 感兴趣,它可以做您想做的事情,但可能更有效。请注意,此函数不是基本标准的一部分,而是扩展的一部分。阅读链接的参考页面了解更多详情。

标签: c string


【解决方案1】:

除了 cmets 关于考虑空终止字节之外,这里的主要问题是:

realloc 返回新分配的区域(可能相同,也可能不同)。

因此,您必须在 realloc(alloc_check,(size+=10)*sizeof(char)); 中分配回 alloc_check,否则只会造成内存泄漏并继续在旧位置写入。

alloc_check = realloc(alloc_check,(size+=10));

(好吧,当尺寸更大时,位置并不能保证每次都改变,但有时当没有足够的连续空间时它必须改变)

旁白:name=(char *)malloc(sizeof(char)*size); => name=malloc(size);(char 的大小始终为 1,无需转换 malloc 指针)

从N5170中提取:

当 sizeof 应用于类型为 char、unsigned char 或 signed char(或其限定版本)的操作数时,结果为 1。

【讨论】:

  • 你是对的 +1。但不适用于sizeof(char),它可以是 !=1(即在 EBCD 系统上);)。 C 标准没有指定它。
  • @Frankie_C 感谢紫外线。我在这里读过sizeof(char)==1 多次,将检查:找到它:stackoverflow.com/questions/40679801/…
  • @Frankie_C : sizeof(char) 被 C 标准保证为 1。只是不能保证1 对应一个 8 位字节(参考CHAR_BIT)。
  • 根据我在 vs2010 中的理解,即使在 *.c 文件中也使用 c++ 编译器,并且您必须 csst malloc。稍后当我靠近我的代码时,我会按照您的建议进行操作。
  • @hellazari 不,Visual Studio 将扩展名为 .c 的文件编译为 C 代码,而不是 C++。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 2013-12-18
  • 2018-02-16
相关资源
最近更新 更多