C语言 需要了解指针算术

nnt7mjpx  于 2023-04-19  发布在  其他
关注(0)|答案(3)|浏览(95)

下面的代码我试图执行指针算术

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr = malloc(100);

    printf("base : %p\n", ptr);
    printf("\n");
    printf("base+1 : %p\n", ptr+1);

    ptr+= 100;
    *ptr = 90;
    printf("addr: %p val : %d\n", ptr, *ptr);

    return 0;
}

输出:

base : 0x5621e46412a0

base+1 : 0x5621e46412a4
addr: 0x5621e4641430 val : 90

提问:

  1. return(100);它会返回100字节吗?
    1.这里我没有类型转换malloc的返回地址,顺便说一句,malloc将返回void类型正确的ptr+1如何递增4字节?
    1.现在增加ptr+100,所以400字节将得到正确的增加?我也可以分配值与出分段故障它是如何工作的?
    试图理解在这种情况下指针算术是如何工作的
oug3syen

oug3syen1#

return(100);它会返回100字节吗?
是的。或者更准确地说:它将为您保留100个字节,并返回该内存区域的地址。
这里我没有类型转换malloc的返回地址,顺便说一句,malloc将返回void类型正确的ptr+1如何递增4字节?
这是不正确的。malloc不返回void,而是返回指向void的指针。这与任何指向任何数据的指针兼容,而无需强制转换。在分配给ptr之后,它是指向int的指针。增量仅取决于指针的类型,即int
现在增加ptr+100,所以400字节将得到正确的增加?我也可以分配值与出分段故障它是如何工作的?
正确(假设您似乎在使用32位系统)。这意味着您正在非法访问您不拥有的内存,并且您不应该访问。这会导致未定义的行为。它可能看起来工作或崩溃。未定义的行为也意味着它没有定义为导致segfault。
参见Undefined, unspecified and implementation-defined behavior

xienkqul

xienkqul2#

  1. return(100);它会返回100字节吗?
    malloc(100)将返回一个指针,指向已保留100字节内存的位置,或者返回一个空指针。
    1.这里我没有对malloc的返回地址进行类型转换,...
    简单赋值运算符(=)自动将其右操作数转换为左操作数的类型。当左操作数是指针时,右操作数可以是以下任意一种:
  • 指向兼容类型或void的指针,但右类型可以省略左类型具有的限定符或
  • 空指针常量。

顺便说一句,malloc将返回void类型,正确的ptr+1如何递增4字节?
C不“记得”来自malloc的返回类型为void *的地址。当计算ptr+1时,ptr的类型用于算术。ptr的类型为int *,因此算术以int为单位执行。
1.现在增加ptr+100,所以400字节将得到增加正确吗?
在分配的空间内,如果C实现为int使用4个字节,则添加 x 将向地址添加4x 个字节。在分配的空间之外,C标准没有定义指针算术的行为。如果分配的空间是1000字节而不是100字节,则ptr+100将计算超出起始400字节的地址。
...也我可以能够分配值与出分割故障它是如何工作的?
内存保护通常以页面为单位工作。如果您使用的内存位于您可以访问的页面内,即使它不是您应该访问的页面中的位置,也不会出现分段错误。或者,如果您计算错误的地址,结果仍然是您可以访问的页面,内存保护不能绝对防止进程的所有地址错误,并且动态分配的内存可能位于允许程序访问的具有许多页的区域中。

bvuwiixz

bvuwiixz3#

1.否;它将返回一个指向至少100个字节的 * 指针 *,或NULL
1.否;它以sizeof(*ptr)递增,在本例中为sizeof(int)。这可能是一个不同于4的值。ptr-to-void与任何没有强制转换的对象指针都是赋值兼容的,在C中,最好不要强制转换malloc返回值。搜索这个网站了解原因。
1.不正确;它以100*sizeof(*ptr)递增。这可能是400以外的值。通过该指针写入是 * 未定义的行为 *,因此任何事情都可能发生,包括没有明显的事情。
要打印指针值,使用%p说明符是不够的,参数必须是指向void的指针,因此必须使用(void*)强制转换,如

printf("base : %p\n", (void*)ptr);

相关问题