C指向2维数组

时间:2012-12-19 12:29:36

标签: c arrays pointers

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

// 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]时,运行软件的mikrocontroller会出现硬故障。

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

我尝试了像

这样的组合
systemMatrix = *(*tmpTimeSlot);

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

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

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

5 个答案:

答案 0 :(得分: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];
    }
}

答案 1 :(得分:4)

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

此外,返回指向局部变量的指针将导致函数返回后悬空指针。

答案 2 :(得分:2)

这里有几个错误。

 TimeSlot **systemMatrix;

这不能用于指向C多维数组(稍后声明);相反,它可以用来指向矢量的矢量,这是一个不同的野兽(看看你的C书了解更多细节)。关键是,要指向一个多维数组,你应该有这样的声明:

 TimeSlot (* systemMatrix)[lines];

是指向长度为lines的向量的指针,可用于处理多维数组(有关详细信息,请参阅here)。现在,这需要在编译时知道lines,因此在您的情况下它是不合适的。

即使您的systemMatrix声明对于您在该函数中执行的赋值是正确的,您也会将该函数内部分配的内存地址分配给该指针,该函数在函数退出后不再存在 - 所以<{1}}返回时,systemMatrix将成为无效指针。

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

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

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

答案 3 :(得分:1)

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

另外。阅读这个问题的答案:Heap allocate a 2D array (not array of pointers)学习如何动态分配二维数组(在堆上,与堆栈相对)。

答案 4 :(得分:1)

两个问题:

  1. 您不得返回指向自动存储的指针。一旦剩下这个功能,该存储就会超出范围。你应该使用malloc()代替。使用超出范围的存储可能会访问堆栈上的垃圾,这可能会导致硬故障。从技术上讲,这在C中称为未定义的行为
  2. 与您的陈述相反,TimeSlot **systemMatrix;不会声明二维数组,而是指向指向Timeslot的指针。有关如何动态创建多维数组的信息,请参阅comp.lang.c FAQ