所以,首先我已经看了几个问题,包括this one,但似乎没有一个问题有帮助。
我只是尝试编写一个使用realloc()
扩展数组大小的函数。
我的代码目前看起来像这样:
unsigned char *xtnd = malloc(4);
xtndc(&xtnd, 4);
// sizeof(*xtnd) should now be 8
void xtndc ( unsigned char ** bytesRef , uint8_t count ) {
*bytesRef = realloc(*bytesRef, (sizeof(**bytesRef)) + count);
}
但无论我做什么,似乎xtnd
的大小总是为4.在运行xtndc()
之后它现在应该是8个字节长。
有什么建议吗?
答案 0 :(得分:2)
**bytesRef
的类型为unsigned char
,因此sizeof(**bytesRef)
为1
。 sizeof
无法跟踪动态分配,它是一个编译时工具,可以为您提供类型的大小,在本例中为unsigned char
。
您必须手动跟踪数组大小以计算新的所需大小。
答案 1 :(得分:1)
您的程序确实会改变内存块的大小。它将原始内存块的大小从4个字节更改为5个字节。它更改为5个字节,因为您实际上正在执行sizeof(unsigned char) + 4
,其中1 + 4 = 5.如果要将大小加倍,请执行count*sizeof(unsigned char) + count
。这里有两点需要注意:
sizeof
函数返回数据类型的大小,而不是分配的字节大小。无法知道动态分配的内存的大小。 realloc
(以及malloc
和calloc
)并不总能保证返回请求的重新分配。它可能会或可能不会一直成功。答案 2 :(得分:0)
我使用以下代码解决了问题。
typedef struct CArrPtr {
unsigned char* ptr;
size_t size;
} CArrPtr;
void xtndc ( CArrPtr *bytesRef, uint8_t count );
. . .
CArrPtr xtnd = { .ptr = malloc(4), .size = 4 };
xtndc( &xtnd, 4 );
// xtnd.size is now 8 bytes
. . .
void xtndc ( CArrPtr *bytesRef, uint8_t count ) {
unsigned char *nptr;
if((nptr = realloc(bytesRef->ptr, bytesRef->size + count)) != 0)
{
bytesRef->ptr = nptr;
bytesRef->size = bytesRef->size + count;
}
}
由于我对C有点新,我从中学到的是malloc
专门创建了一个指向内存块的指针,但是你无法直接访问有关内存块的信息。相反,您必须将使用malloc创建的数组的大小存储在某处。
由于过去我一直使用unsigned char arr[size];
初始化数组,然后在其上使用sizeof
,我的印象是sizeof
返回了数组的大小,这是当然错了,因为它给你一个类型的大小。
很高兴我能从中学到一些东西。
答案 3 :(得分:0)
sizeof
用于计算数据类型或数组的大小。指针和数组非常相似,但它们是不同的东西。对于int *ap
,sizeof(ap)
将在x86上返回4,sizeof(*ap)
将返回4;对于int a[10]
,sizeof(a)
将返回40.
sizeof
表达式在编译时处理,因此在运行程序之前它将是写入可执行文件的常量。
malloc
和realloc
不保持大小。
如果realloc
成功,它将重新分配请求的大小。因此,您不需要在realloc
返回后检查大小,但是您应该检查realloc
的返回值,以确保realloc
成功。