为什么createArray
函数将指针返回0?
我想我应该使用malloc来修复它,但是为什么呢?
int *createArray(int size)
{
int i;
int arr[size];
i = 0;
while (i < size)
{
arr[i] = i;
i++;
}
return arr;
}
int main()
{
int *ar;
printf("%i", (createArray(10)));
}
答案 0 :(得分:1)
arr变量分配在堆栈上。 从函数返回时,将释放堆栈。 然后,您返回的指针将指向一个无效的内存位置,该位置可能设置为null。
答案 1 :(得分:1)
从函数返回数组时,实际上是在返回指向数组第一个元素的指针。当函数返回时,其局部变量使用的内存不再有效。
因此,您将返回一个指向不再存在的变量的指针。以任何方式使用该指针都会调用undefined behavior。在这种特殊情况下,无效地址可以被取消引用,并且恰好包含值0,但是不能保证在更改程序时行为会保持一致。
为此,您需要动态分配内存。然后可以在程序的整个生命周期内使用它。
int *arr = malloc(sizeof(*arr) * size);
这也意味着您在使用完该内存后需要free
:
int *ar = createArray(10);
printf("%i", ar[0]);
free(ar);
答案 2 :(得分:1)
基本问题是您的函数正在返回局部变量的地址。函数返回后,该局部变量将不再存在,因此指向它的任何指针都是无效的。
为更正您的代码中的某些问题,我在顶部添加了func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: EmojiCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "EmojiCollectionViewCell", for: indexPath) as! EmojiCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay c: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cell = c as! EmojiCollectionViewCell
let imageName = String(format:"%@-%@", categories[selectedCategory], NSNumber(value: indexPath.row + 1));
let emojiImage = UIImage(named: imageName)
cell.setupWithEmojiImage(image: emojiImage)
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying c: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cell = c as! EmojiCollectionViewCell
cell.setupWithEmojiImage(image: nil)
}
(#include <stdio.h>
必需),并将您的printf
调用从更改为
printf
到
printf("%i", (createArray(10)));
当我使用gcc编译并运行程序时,输出为:
printf("%p\n", (void*)createArray(10));
表示您的函数正在返回空指针。 (这不是“指向null的指针”;指针是为null。)这不是我期望的;我期望一个无效的垃圾指针值。 (当我使用tcc而不是gcc时,会得到(nil)
。)
很显然,gcc识别出您的代码具有未定义的行为,并将0x7fffd95a7140
语句替换为return
。这是一个完全合法的转换(它可能会阻止您的程序使用无效的指针进行令人讨厌的操作,从而修改程序不拥有的内存)。
底线:您的程序具有未定义的行为,并且您无法假设其将执行的操作。是的,使用return NULL;
分配数组并返回分配的数组的地址是修复它的一种方法。