使用calloc并手动输入字符会导致崩溃

时间:2014-10-02 18:25:50

标签: c calloc

我这里有这个代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int *size;
    int i = 0;
    char buf[] = "Thomas was alone";
    size = (int*)calloc(1, sizeof(buf)+1);
    for(i=0; i<strlen(buf); i++)
    {
        *(size+i) = buf[i];
        printf("%c", *(size+i));
    }
    free(size);
}

据我所知,calloc保留了第一个arg的大小乘以第二个的memspace,在这种情况下为18. buf的长度为17,因此for循环应该没有任何问题。

运行此程序会产生预期的结果(它打印出Thomas独自一人),但它也会立即崩溃。除非我调高calloc的大小(比如乘以10),否则这种情况会持续存在。

我可能错误地理解了什么吗? 我应该使用函数来防止这种情况发生吗?

3 个答案:

答案 0 :(得分:3)

int *size表示您需要:

size = calloc(sizeof(int), sizeof(buf));

您为char数组分配了足够的空间,但没有int的数组(除非您在sizeof(char) == sizeof(int)的奇数系统上,这是理论上的可能性而不是实际的)。这意味着您的代码写入远远超出分配内存的末尾,这导致崩溃。或者您可以使用char *size,在这种情况下,calloc()的原始呼叫就可以了。

请注意sizeof(buf)包含终止null; strlen(buf)没有。这意味着您使用+1字词稍微过分。

你也可以完全明智地写size[i]而不是*(size+i)

答案 1 :(得分:2)

size的类型更改为char

您正在使用int,当您在此处添加指针*(size+i)时,您将超出范围。 指针算术会考虑类型,在这种情况下,int不是char。 sizeof int大于系统中的char。

答案 2 :(得分:0)

为char数组分配场所而不是int数组:

  • char在内存中是1个字节(最常见)
  • int是内存中的4个字节(最常见)

所以你分配1 * sizeof(buf) + 1 = 18个字节
例如在记忆中:

buf [0] = 0x34523
buf [1] = 0x34524
buf [2] = 0x34525
buf [3] = 0x34526

但是当你使用*(size + 1)时,你不会在1个字节上移动指针,但是对于sizeof(int),所以4个字节。 所以在记忆中它看起来像:

size [0] = 0x4560
size [1] = 0x4564
大小[2] = 0x4568
size [3] = 0x4572

所以经过几次循环后你就会失去记忆。

calloc(1, sizeof(buf) + 1);更改为calloc(sizeof(int), sizeof(buf) + 1);以获得足够的内存。

第二个想法,我认为是你学习它如何运作的一些例子? 我的建议是:

  • 使用相同类型的指针和变量。
  • 在分配不同类型的变量时,请使用显式转换(在此示例中) *(size+i) = (int)buf[i];