指向结构的不完整指针数组检测到堆栈粉碎

问题描述

对于看起来很糟糕的代码,我提前表示歉意。这只是一个概念证明。

该程序的目的是填充“数据包”,但通过 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 在堆栈上,编译器根本不会为灵活数组成员分配任何内存。所以写入它会破坏堆栈(即覆盖堆栈上的重要数据)。