2012-12-19 216 views
1

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

// 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); 

等,但他们都不工作。

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

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

+1

二维数组不会转换为双指针。 –

回答

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

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

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

+1

不仅如此,而且双指针是指向多维数组的错误类型。 –

+0

@MatteoItalia是的,但这是马丁需要理解的第一件事:) – piokuc

4

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

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

1

两个问题:

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

这里有几个错误。

TimeSlot **systemMatrix; 

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

TimeSlot (* systemMatrix)[lines]; 

这是一个指向长度lines的载体,可用于处理多维阵列(见here更多细节)。现在,这需要在编译时知道lines,所以它不适合您的情况。

即使您的systemMatrix声明对于您在该函数中执行的任务是正确的,您将为该指针指定分配给该函数的内存地址,该函数在函数退出后不再存在 - 因此您的systemMatrix会只要setup返回,就成为无效指针。

您需要的是内存的动态分配。这使您可以指定该内存的任意生命周期并使用双括号语法。首先,你分配一个与你需要的行数一样大的指针向量(在malloc的调用中乘以sizeof(int *));然后,然后,您分配行向量并将它们中的每一个分配到它在列向量中的位置。有关此(和其他)动态分配多维向量的解决方案的更多详细信息,请参见this answer

不要忘了free每个分配的向量,当你不再需要它们了!