在代码块中使用malloc显示分配内存大小的错误值

在代码块中使用malloc显示分配内存大小的错误值,c,dynamic,malloc,C,Dynamic,Malloc,已分配内存的大小 int main() { char *aPtr[10]; aPtr[0] = (char *)malloc(20 * sizeof(char)); aPtr[0] = "This is a test"; aPtr[1] = (char *)malloc(20 * sizeof(char)); aPtr[1] = "This is a test2"; printf("%s\n%s\n", aPtr[0], aPtr[1]

已分配内存的大小

int main() {

    char *aPtr[10];

    aPtr[0] = (char *)malloc(20 * sizeof(char));

    aPtr[0] = "This is a test";

    aPtr[1] = (char *)malloc(20 * sizeof(char));

    aPtr[1] = "This is a test2";

    printf("%s\n%s\n", aPtr[0], aPtr[1]);

    printf("%d", sizeof(aPtr[0]));
}

在这种情况下,为什么
aPtr[0]
的大小显示为4个字节而不是20个字节。我不明白为什么会发生这种情况。

您有一个
char
指针数组。所以指针的大小和它指向的对象的大小是不同的。这里您正在打印一个指针的大小,它是固定的,即对于32位机器,它是4个字节。

您有一个
char
指针数组。所以指针的大小和它指向的对象的大小是不同的。这里您打印的是一个固定的指针大小,即对于32位机器,它是4个字节。

aPtr
是指向字符的指针数组。因此,
aPtr
的每个元素都是指向
char
char*
的单个指针。特别是,
aPtr[0]
是一个
char*
。因此,
sizeof(aPtr[0])
提供该指针的大小。在许多机器上(在“32位机器”上),指针的大小为32位或4字节

根据您的问题,听起来您对指针指向的数据的大小很感兴趣。那完全不同。(同样,请仔细了解我们在指针和指向数据之间所做的区分。)在这种情况下,查找指向数据的大小可能很棘手,结果可能根本不涉及
sizeof
操作符

如果你想知道一个malloc’ed内存块的大小,结果是没有可移植的方法。也就是说,在你说了
p=malloc(20)
之后,没有办法问“嘿,
malloc
。你给我的指针,我让你分配一些内存,我又让你分配了多少内存?我忘了。“如果你需要知道你的malloc指针指向多少内存,你必须以某种方式记住它。”

另一方面,如果你想知道一个字符串有多长,那很简单:只要调用
strlen
。例如,对程序的合理修复是将最后一行

printf("%d", strlen(aPtr[0]));
实际上,由于
strlen
(如
sizeof
)返回一个名为
size\u t
的特殊类型,它可能比
int
更大,因此编写此函数的更方便的方法是

printf("%zu", strlen(aPtr[0]));

但是回到你最初的计划,我们应该谈谈另一个误解。你说

aPtr[0] = (char *)malloc(20*sizeof(char));
aPtr[0] = "This is a test";
现在,我知道大家都知道内存分配很重要,这是真的,但在这种情况下,结果是分配了20字节的内存,然后把它扔掉了。仔细观察:
malloc
返回一个指针值(指向新分配的内存),然后将其分配给(将值存储在)
aPtr[0]
。但是,在下一行中,您将
aPtr[0]
分配给另一个指针,指向静态分配的字符串
“这是一个测试”
。先前的值(由
malloc
返回的值)丢失

你可能想在这里写的是

aPtr[0] = malloc(20);
strcpy(aPtr[0], "This is a test");
现在,我们对字符串常量做了一些完全不同的事情。
“这是一个测试”
。我们不是简单地给它分配一个指针,而是将while字符串(实际上库函数strcpy正在复制整个字符串)逐字节复制到aPtr[0]指向的指针中,也就是刚刚从
malloc
返回的指针。(在这个最新的示例中,我还将
malloc
的返回值的不必要的强制转换删除为
(char*)
,并将不必要的乘法删除为
sizeof(char*)

注意,在这种情况下(现在您实际使用的是malloc'ed内存),malloc'ed内存的大小很重要。如果你说

aPtr[0] = malloc(10);
strcpy(aPtr[0], "This is a test");
那你就有大问题了

最后,对于“字符串有多大?”这个问题还有另外一个答案,尽管它通常不太有用,在这种情况下也肯定不有用。但是如果你想,你可以写

printf("%zu\n", sizeof("This is a test"));
这将打印15张。(它比您认为的字符串长度多打印一个,因为字符串常量的大小计数包括终止的
\0
字符。)

aPtr
是指向字符的指针数组。因此,
aPtr
的每个元素都是指向
char
char*
的单个指针。特别是,
aPtr[0]
是一个
char*
。因此,
sizeof(aPtr[0])
提供该指针的大小。在许多机器上(在“32位机器”上),指针的大小为32位或4字节

根据您的问题,听起来您对指针指向的数据的大小很感兴趣。那完全不同。(同样,请仔细了解我们在指针和指向数据之间所做的区分。)在这种情况下,查找指向数据的大小可能很棘手,结果可能根本不涉及
sizeof
操作符

如果你想知道一个malloc’ed内存块的大小,结果是没有可移植的方法。也就是说,在你说了
p=malloc(20)
之后,没有办法问“嘿,
malloc
。你给我的指针,我让你分配一些内存,我又让你分配了多少内存?我忘了。“如果你需要知道你的malloc指针指向多少内存,你必须以某种方式记住它。”

另一方面,如果你想知道一个字符串有多长,那很简单:只要调用
strlen
。例如,对程序的合理修复是将最后一行

printf("%d", strlen(aPtr[0]));
实际上,由于
strlen
(如
sizeof
)返回一个名为
size\u t
的特殊类型,它可能比
int
更大,因此编写此函数的更方便的方法是

printf("%zu", strlen(aPtr[0]));

但是回到你的