C语言 从 C 函数返回指向 uint8_t 数组的指针 - 获取编译器错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23597259/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
returning a pointer to an array of uint8_t from a C function - get compiler errors
提问by banditKing
I have a function:
我有一个功能:
uint8_t* createTestBuffer()
{
uint8_t buffer[] = {5,7,3,4,1,9,3};
return &buffer;
}
runing it:
运行它:
uint8_t *buff = createTestBuffer();
returns compiler errors:
返回编译器错误:
c_programming.c:11:9: warning: incompatible pointer types returning 'uint8_t (*)[7]' from a function with result type
'uint8_t *' (aka 'unsigned char *') [-Wincompatible-pointer-types]
return &buffer;
Im returning a pointer to an array of uint8_t from my function. So what am I getting wrong here?
我从我的函数返回一个指向 uint8_t 数组的指针。那么我在这里做错了什么?
回答by Jonathan Leffler
The compiler told you that return &buffer;is returning a pointer to an array of 7 uint8_t(spelled uint8_t (*)[7]), but you said the function returns uint8_t *, and these are different and incompatible pointer types.
编译器告诉你return &buffer;返回一个指向 7 数组的指针uint8_t(拼写为uint8_t (*)[7]),但你说函数返回uint8_t *,这些是不同且不兼容的指针类型。
If you wrote return buffer;, the types would be correct but the code would still be wrong. You can't safely return a pointer to a local array that's on the stack.
如果您编写return buffer;,类型将是正确的,但代码仍然是错误的。您不能安全地返回指向堆栈上的本地数组的指针。
Either make it static const uint8_t buffer[] = { … };and change the function return type to const uint8_t *, and use accordingly (which is thread-safe because the data never changes):
要么制作它static const uint8_t buffer[] = { … };并将函数返回类型更改为const uint8_t *,并相应地使用(这是线程安全的,因为数据永远不会改变):
const uint8_t *createTestBuffer(void)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
return buffer;
}
Or use dynamic allocation in some form as:
或者以某种形式使用动态分配:
uint8_t *createTestBuffer(void)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
uint8_t *rv = malloc(sizeof(buffer));
if (rv != 0)
memmove(rv, buffer, sizeof(buffer));
return rv;
}
Note that the calling code here needs to check that it gets a non-null pointer back again, and it must also ensure it calls free()on the returned pointer unless it is null (when calling free()becomes optional).
请注意,这里的调用代码需要检查它是否再次获取了非空指针,并且还必须确保它调用free()返回的指针,除非它为空(当调用free()变为可选时)。
Or make the caller pass the buffer – living dangerously by assuming that the user knows to pass enough space:
或者让调用者传递缓冲区——通过假设用户知道传递足够的空间来危险地生活:
void createTestBuffer(uint8_t *output)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
memmove(output, buffer, sizeof(buffer));
}
Or living less dangerously:
或者活得不那么危险:
static inline size_t min(size_t a, size_t b) { return (a < b) ? a : b; }
void createTestBuffer(uint8_t *output, size_t outlen)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
memmove(output, buffer, min(sizeof(buffer), outlen));
}
There are other ways to handle 'output buffer smaller than copied buffer'; this code copied as much as was safe, but you could return a 0 or 1 status indicating truncation, or assert that the supplied length is not smaller than the required length, or …
还有其他方法可以处理“输出缓冲区小于复制缓冲区”;此代码尽可能安全地复制,但您可以返回 0 或 1 状态指示截断,或断言提供的长度不小于所需的长度,或者……
回答by zmo
here you have two errors:
在这里你有两个错误:
your first error, is that you're returning your buffer using the &operator (aka address of), which gives a pointer to your variable's address. Your array being already uint8_t*you're returning uint8_t(*)[7], as the error is telling you. And the compiler is grumpy, because you're trying to return that one whereas your function shall return the former.
您的第一个错误是您使用&运算符(也称为 的地址)返回缓冲区,该运算符提供指向变量地址的指针。正如错误告诉您的那样,您的数组已经uint8_t*在返回uint8_t(*)[7]。编译器脾气暴躁,因为您试图返回那个,而您的函数将返回前者。
But know that actually there's an even more important error in your code, as first spotted out by @TimCooper:
但是要知道,正如@TimCooper 首先发现的那样,您的代码中实际上存在一个更重要的错误:
you're allocating a variable within the scope of a function, and want to use it outside of that function. In C, when you declare a variable within a function, the memory used to allocated it is freed upon exit of that function, so even if you correct the typing of your function that won't work as expected.
您正在函数范围内分配一个变量,并希望在该函数之外使用它。在 C 中,当您在函数中声明一个变量时,用于分配它的内存会在该函数退出时被释放,因此即使您更正了无法按预期工作的函数类型。
You need to either declare your uint8_t array outside of the function, and pass it as a parameter to your function:
您需要在函数外部声明您的 uint8_t 数组,并将其作为参数传递给您的函数:
uint8_t* createTestBuffer(uint8_t* array) {
array[0] = 5;
array[1] = 7;
array[2] = 3;
array[3] = 4;
array[4] = 1;
array[5] = 9;
array[6] = 3;
return array;
}
or you need to use malloc to allocate the memory in the heap instead of allocating it in the stack:
或者您需要使用 malloc 在堆中分配内存而不是在堆栈中分配它:
uint8_t* createTestBuffer() {
uint8_t* array = , malloc(sizeof(uint8_t)*7);
array[0] = 5;
array[1] = 7;
array[2] = 3;
array[3] = 4;
array[4] = 1;
array[5] = 9;
array[6] = 3;
return array;
}
but then you'll have to not forget to free()the buffer variable once you've finished using it.
但是free()一旦你用完它,你就必须不要忘记缓冲区变量。
回答by ezaquarii
You get the warning because bufferis of type uint8_t*. The statement &bufferis of type uint8_t**- a pointer to a pointer.
您收到警告是因为buffer类型为uint8_t*。该语句&buffer属于类型uint8_t**- 指向指针的指针。
In C and C++ an array name is the same as a pointer.
在 C 和 C++ 中,数组名称与指针相同。
char s[4] = { 'a', 'b', 'c', 'uint8_t* createTestBuffer()
{
uint8_t *buffer = (char*)malloc( 3 * sizeof(char) );
buffer[0] = 10;
buffer[1] = 20;
buffer[2] = 30;
return buffer;
}
' };
char *p = &s[0];
printf("%s", s);
printf("%s", p);
The second thing is that you're returning a pointer to an array CREATED ON STACK. This array is not valid after function exit. In practice you're returning a dangling pointer.
第二件事是您要返回一个指向在堆栈上创建的数组的指针。该数组在函数退出后无效。实际上,您返回的是一个悬空指针。
If you want to return a pointer you should allocate memory on heap, using malloc():
如果你想返回一个指针,你应该在堆上分配内存,使用malloc():
void createTestBuffer(uint8_t **buffer, size_t *size)
{
*buffer = (char*)malloc( 3 * sizeof(char) );
buffer[0] = 10;
buffer[1] = 20;
buffer[2] = 30;
*size = 3;
}
But there is another problem. You're returning a pointer to a memory block, but you don't know how big the buffer is. You can modify the function to "return" 2 values this way:
但还有一个问题。您正在返回一个指向内存块的指针,但您不知道缓冲区有多大。您可以通过这种方式修改函数以“返回”2 个值:
char *buf;
size_t size;
createTestBuffer(&buf, &size);
and call it like this:
并这样称呼它:
##代码##Enjoy!
享受!

