问题描述
对于看起来很糟糕的代码,我提前表示歉意。这只是一个概念证明。
该程序的目的是填充“数据包”,但通过 potmeter
结构的可单独访问的指针。
该程序使用完整的 *potPointers[3]
类型。它也适用于不完整类型 *potPointer[]
。但是在成功运行后,我得到:
*** stack smashing detected ***: terminated Aborted (core dumped)
如何成功处理指向结构体的不完整指针数组?
我当然可以输入 #define
,但还有其他方法吗?
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define BYTES_DATAWORD_POTMETER 2
typedef struct
{
uint8_t test;
uint8_t *datawordPointer[2];
}potmeter;
typedef struct
{
uint8_t amountOfPots;
size_t datapacket_size;
uint8_t *datapacket; // needs to be malloc'ed,don't forget to free it.
// Sort of working with *** stack smashing detected ***: terminated Aborted (core dumped)
potmeter *potPointers[];
// Works without stack smashing.
// potmeter *potPointers[3];
}overall;
void initPointersToDatapackett(overall *allePots)
{
uint8_t counter = 0;
for(int i = 0; i < allePots->amountOfPots; i++)
{
// Allocate memory per pot
allePots->potPointers[i] = malloc(sizeof(potmeter));
// Point pointers to dataword of overall
allePots->potPointers[i]->datawordPointer[0] = &allePots->datapacket[counter++];
allePots->potPointers[i]->datawordPointer[1] = &allePots->datapacket[counter++];
}
}
int main()
{
overall AllePotMeters;
AllePotMeters.amountOfPots = 3;
AllePotMeters.datapacket = malloc(AllePotMeters.amountOfPots*BYTES_DATAWORD_POTMETER);
initPointersToDatapackett(&AllePotMeters);
//Test content of pointers to dataword
*AllePotMeters.potPointers[0]->datawordPointer[0] = 'A';
*AllePotMeters.potPointers[0]->datawordPointer[1] = 'B';
*AllePotMeters.potPointers[1]->datawordPointer[0] = 'C';
*AllePotMeters.potPointers[1]->datawordPointer[1] = 'D';
*AllePotMeters.potPointers[2]->datawordPointer[0] = 'E';
*AllePotMeters.potPointers[2]->datawordPointer[1] = '\0';
printf("String test %s\n",AllePotMeters.datapacket);
free(AllePotMeters.potPointers[0]);
free(AllePotMeters.potPointers[1]);
free(AllePotMeters.potPointers[2]);
free(AllePotMeters.datapacket);
return 0;
}
解决方法
您在此处使用的功能称为 "flexible array member"。如果数组大小为空,则 overall
结构的大小根本不包括数组。因此,overall
类型的变量不包含您的 potPointers
的任何内存。
为 potPointers
分配空间是程序员的责任。请注意,这通常意味着使用 struct
动态分配 malloc
。然后,您(程序员)可以告诉它分配比 sizeof(overall)
更多的内存。
例如:
overall *AllePotMeters = malloc(sizeof(overall) + 3 * sizeof(potmeter *));
如果 AllePotMeters
在堆栈上,编译器根本不会为灵活数组成员分配任何内存。所以写入它会破坏堆栈(即覆盖堆栈上的重要数据)。