1

我遇到了指向二维数组的指针的问题。指针应指向可变大小的数组。

// create pointer to 2 dimensional array
TimeSlot **systemMatrix; // this is a global variable

在一个函数中,我想创建一个新数组。

void setup(uint16_t lines, uint16_t coloumns) {
    // create 2 dimensional array. size can be set here.
    TimeSlot tmpTimeSlots[lines][coloumns];

    // make the pointer point to this array
    systemMatrix = tmpTimeSlots; // WARNING
}

但是当我让指针指向数组时,编译器会说“警告:来自不兼容的指针类型的赋值”。此外,当从另一个函数访问 systemmatrix[2][5] 时,运行软件的微控制器会出现硬故障。

稍后在访问 tmpTimeSlots 的元素时需要变量 systemMatrix。

我尝试过像这样的组合

systemMatrix = *(*tmpTimeSlot);

等等,但它们似乎都不起作用。

任何帮助表示赞赏:) 谢谢!

编辑:好的问题理解并解决,非常感谢!

4

5 回答 5

6

二维数组!= 双指针。

您几乎肯定需要为此进行动态内存分配。您还想深度复制数组的内容 - 它是一个非静态局部变量,因此超出其范围是无效的。结果你做不到TYPE arr[sz]; return arr;

const size_t width = 3;
const size_t height = 5;
TimeSlot tmpTimeSlot[width][height];

systemMatrix = malloc(width * sizeof systemMatrix[0]);
for (int i = 0; i < width; i++) {
    systemMatrix[i] = malloc(height * sizeof systemMatrix[i][0]);
    for (int j = 0; j < height; j++) {
        systemMatrix[i][j] = tmpTimeSlot[i][j];
    }
}
于 2012-12-19T12:35:04.750 回答
4

您的systemMatrix指针不是指向二维数组的指针,而是双重解引用。您需要像这样声明它:TimeSlot (*systemMatrix)[columns];- 这是二维数组指针的正确类型。但是,您需要columns在声明(C99 中)或常量(C99 之前)的位置知道值。

另外,返回一个指向局部变量的指针会导致函数返回后指针悬空。

于 2012-12-19T12:35:07.947 回答
2

这里有几个错误。

 TimeSlot **systemMatrix;

这不能用于指向 C 多维数组(稍后声明);相反,它可以用来指向一个向量的向量,这是一个不同的野兽(有关这方面的更多详细信息,请查看您的 C 书籍)。关键是,要指向一个多维数组,你应该有这样的声明:

 TimeSlot (* systemMatrix)[lines];

这是一个指向长度向量的指针lines,可用于寻址多维数组(有关详细信息,请参见此处)。现在,这需要lines在编译时知道,所以它不适合你的情况。

即使您的systemMatrix声明对于您在该函数中所做的分配是正确的,您也会将在该函数内部分配的内存地址分配给该指针,该地址在函数退出后不再存在 - 因此您systemMatrix将尽快成为无效指针作为setup回报。

您在这里需要的是动态分配内存。这允许您为该内存指定任意生命周期并使用双括号语法。

首先,您分配一个指针向量,与您需要的行数一样大(sizeof(int *)在调用中乘以malloc);然后,您分配行向量并将它们中的每一个分配到列向量中的位置。有关动态分配多维向量的此(和其他)解决方案的更多详细信息,请参阅此答案

当您不再需要它们时,不要忘记free每个分配的向量!

于 2012-12-19T12:46:35.327 回答
1

您正在尝试保存指向本地对象的指针(在堆栈上分配)并在超出范围后使用它。这是错误的,函数完成后指针将失效。

还。阅读这个问题的答案:堆分配一个二维数组(不是指针数组)来学习如何动态分配一个二维数组(在堆上,与堆栈相反)。

于 2012-12-19T12:31:55.127 回答
1

两个问题:

  1. 您不得返回指向自动存储的指针。一旦离开该功能,该存储就会超出范围。您应该改用 malloc() 。使用超出范围的存储可能会访问堆栈上的垃圾,这可能会导致硬故障。从技术上讲,这在 C中称为未定义行为。
  2. 与您的说法相反,TimeSlot **systemMatrix;没有声明一个二维数组,而是一个指向 a 的指针的指针Timeslot。有关如何动态创建多维数组的信息,请参阅comp.lang.c 常见问题解答。
于 2012-12-19T12:35:33.940 回答