动态分配和指针

时间:2014-02-14 14:43:19

标签: c pointers dynamic-allocation

int *ptr;      
ptr=(int *)malloc(sizeof(int)*2);       
ptr=100;    /*What will happen if I put an asterisk(*) indicating *ptr=100? */            
ptr++;        
printf("ptr=%d",*ptr);         
free(ptr);       

所以,我希望指针增加。我为指针分配了4(2 * 2)的大小。但是我无法理解指针如何仅增加2.如果我在第3行放一个星号,那就是* ptr = 100;它显示了别的东西。

5 个答案:

答案 0 :(得分:3)

如果您有int * ptr,则ptr++会将指针增加一个int的大小。如果int是您平台上的两个字节,那就是它增加2的原因。

*ptr = 100会将值100存储在int指向的ptr,即您分配给您的int中的第一个malloc() ptr = 100致电。

100会尝试将内存地址ptr分配给malloc(),这几乎肯定不是您想要的,因为您将丢失对内存的引用{{1编辑,内存位置100的内容对您来说可能没有意义,也可能对您无法访问。

目前的情况是,如果您要执行*ptr = 100然后ptr++,则printf()调用将导致未定义的行为,因为您已将指针递增指向未初始化内存(即您使用int调用分配的两个malloc()中的第二个),然后您尝试输出其内容。

另一方面,

(*ptr)++会将100值增加到101,保持ptr的值不变,您的printf()调用就可以了,并输出101。您分配的两个int中的第二个仍然未初始化,但如果您不尝试访问它,则没有问题。

另外,不要从malloc()转换回报,ptr=(int *)malloc(sizeof(int)*2)应为ptr=malloc(sizeof(int)*2),或者更好,ptr = malloc(sizeof(*ptr) * 2);

答案 1 :(得分:3)

试试这个:

int *ptr;
ptr = malloc(2 * sizeof *ptr);
printf("ptr = %p.\n", (void *) ptr); // Examine pointer before increment.
ptr++;
printf("ptr = %p.\n", (void *) ptr); // Examine pointer after increment.

您将看到ptr的值增加int中的字节数。 C语言自动以指向元素为单位进行指针运算。因此,C中int指针的单个增量在机器级别变为int的字节数增量。


备注

%p是打印指针时使用的正确说明符,而不是%d。此外,指针必须强制转换为void *const void *

ptr = malloc(2 * sizeof *ptr);是一种比原始代码更清晰的分配内存和分配指针的方法,因为:

  • 如果您更改sizeof *ptr的类型,则使用ptr会导致代码自动调整。不必在两个地方更改类型(声明ptr并且调用malloc的地方),一次更改就足够了。这减少了错误的机会。
  • malloc不需要转换为目标类型。它返回void *,C将自动转换为作业的目标类型而不会抱怨。 (C ++是不同的。)如果你投射它仍然可以工作,但是这可以掩盖另一个问题:如果你不小心没有声明malloc(因为没有包含<stdlib.h>,并且在旧版本中编译C的版本,malloc将被隐式声明为返回int,并且强制转换将掩盖错误。在没有强制转换的情况下保留表达式将导致在发生这种情况时产生警告消息。

答案 2 :(得分:2)

此行将指针中的地址值更改为某些废话(100将不是任何有效地址):

ptr=100;

然后将指针递增到100 + sizeof(int),因为指针的类型为int*,它会自动按字节数递增地址,以获得ptr指向的下一个整数。

在下一行你取消引用无效指针,这样你的代码就会崩溃,但如果你的指针有有效的地址,命令就可以了:

printf("ptr=%d",*ptr);

修复代码只是不要更改指针本身,而是更改数据:

int *ptr;      
ptr=(int *)malloc(sizeof(int)*2);       
*ptr=123;    /*What will happen if I put an asterisk(*) indicating *ptr=100? */            
printf("ptr=%d",*ptr);
ptr++;
*ptr=234;     
printf("ptr+1=%d",*ptr);
// you can set or get your data also this way:
ptr[0] = 333;
ptr[1] = 444;
printf("ptr[0]=%d",ptr[0]);
printf("ptr[1]=%d",ptr[1]);
free(ptr);

答案 3 :(得分:2)

首先需要了解的是POINTER指向ADDRESS,当你将100分配给ptr时,它意味着你的指针ptr现在指向地址为100的内存位置。

其次指针算法取决于指针的类型,在您的情况下,ptr是指向整数的指针。因此当你增加ptr时,这意味着它将跳转到下一个整数的内存位置。因此,ptr增加2(平台上一个int占用的内存)

答案 4 :(得分:0)

简单

ptr=100;

通过这个你试图将int作为地址存储到指针,这是无稽之谈。
换句话说,您正在尝试将指针ptr指向地址100,而不是地址。

但是

*ptr=100;

您正尝试将值100存储到ptr指向的地址,该地址有效。

另外

ptr++;

表示现在ptr指向ptr+4或(ptr+2对于16位编译器,如tc)地址。

同样对于您的特定代码,您只是更改和递增ptr指向的地址,但您不会在ptr指向的地址处存储任何值。 因此,您的代码将打印垃圾值,否则它也可能会崩溃,因为100不是有效地址。

你也应该这样做

ptr=(int*)100;

会删除

warning: assignment makes pointer from integer without a cast [enabled by default]

但仍然是未定义的行为。