#include <stdio.h>
#include <stdlib.h>
int main()
{
char *myptr = calloc(500,1);
char *myptr2 = myptr;
*myptr++ = 'A';
*myptr++ = 'B';
*myptr = ' ';
/* This should dereference the beginning of the memory and print until myptr[2] which is ' ' */
printf("Myptr2 points to: %sn", *myptr2);
free(myptr);
return(EXIT_SUCCESS);
}
为什么创建一个sigsev行13(printf line)?它应该指向内存的开始,然后printf打印直到击中' 0'。
您可以从概念上说出问题是什么?如果您将指向记忆的指针放置,这将导致什么?
当您具有格式字符串中的%s
插槽时,printf
希望将char*
视为相应的参数。这就是为什么您应该通过 myptr2
(是 'A'
的地址,可以从中推导字符串字符的后续地址)。
如果您通过*myptr2
,则基本上是传递字符'A'
本身(没有任何有关该特定'A'
在哪里的信息 - 它可以允许printf
读取字符串的其余部分)。简而言之,printf
期望在那里指针,因此它试图将相应的参数视为指针。
现在请注意,您传递的字符(通过删除char*
,因此获得具有'A'
值的char
的大小为1字节,而指针的大小通常为4或8个字节。这意味着printf
很可能会读取由字符和堆栈中的一些随机数据组成的垃圾地址。在这种情况下,无法保证该程序会发生什么,因此整个事件都调用了不确定的行为。
在您的代码中,您不应在printf的第二个参数中删除myptr2,因此您必须替换:
printf("Myptr2 points to: %sn", *myptr2);
with:
printf("Myptr2 points to: %sn", myptr2);
与printf一起使用%s时,您必须在字符串的第一个字符上给出指针。