【问题标题】:Incomplete pointer array to struct. Stack smashing detected指向结构的不完整指针数组。检测到堆栈粉碎
【发布时间】:2021-08-23 21:13:28
【问题描述】:

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

该程序的目的是填充“数据包”,但通过 potmeter 结构的可单独访问的指针。

该程序适用于完整类型的*potPointers[3]。它也适用于不完整的类型*potPointer[]。但是在成功运行后,我得到:

***检测到堆栈粉碎***:终止 中止(核心转储)

如何成功处理指向结构的不完整指针数组? 我当然可以发#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;
}

【问题讨论】:

  • 在我看来potmeter *potPointers[] 很奇怪。在一个数据包中,我希望有一个像potmeter potPointers[] 这样的类型,因为你想要一个连续的内存缓冲区发送到某个地方。在这方面,这段代码对我来说毫无意义。您似乎也没有在任何地方为datawordPointer 分配内存。
  • datawordPointer指向整个结构体的dataword,是malloc的。
  • [] 并不意味着“这个数组会按需增长”或“这个数组神奇地拥有足够的元素来满足所有需求”。你认为这意味着什么?
  • 我想我找到了解决方案。通过使potPointer 成为双指针:potmeter **potPointers;,然后 malloc 它需要的指针数量。
  • @n.1.8e9-where's-my-sharem。是的,你是对的。它永远不知道它的大小,而且是不完整的。

标签: c flexible-array-member


【解决方案1】:

您在此处使用的功能称为"flexible array member"。如果数组大小为空,则 overall 结构的大小根本不包括数组。所以overall 类型的变量不包含您的potPointers 的任何内存。

potPointers 分配空间是程序员的责任。请注意,这通常意味着使用malloc 动态分配struct。然后,你(程序员)可以告诉它分配比sizeof(overall)更多的内存。

例如:

overall *AllePotMeters = malloc(sizeof(overall) + 3 * sizeof(potmeter *));

如果AllePotMeters 在堆栈上,编译器根本不会为灵活数组成员分配任何内存。所以写入它会破坏堆栈(即覆盖堆栈上的重要数据)。

【讨论】:

  • 谢谢。这就是我一直在寻找的。顺便说一句,使用双指针也是一个很好的解决方案吗?像这样:``` potmeter **potPointer; potPointers = malloc(3*sizeof(potmeter *)); ```
猜你喜欢
  • 1970-01-01
  • 2019-10-31
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多