C 程序内存冲突取决于 std::cout (?)
Posted
技术标签:
【中文标题】C 程序内存冲突取决于 std::cout (?)【英文标题】:C program memory violation dependant on std::cout (?) 【发布时间】:2017-10-25 17:36:16 【问题描述】:我已经用 C++ 为 Python 编写了一个扩展,目前正在调试它。 该扩展需要 3 个 numpy 矩阵并因此产生 2 个。对于执行实际计算的内部 C++ 函数,我传递了 3 个浮点 C 数组(只是从输入 numpy 数组展平和转换),并返回一个 C 浮点数组数组。一切都按预期工作,但仅如果我在返回之前打印此输出数组数组。
这到底是怎么回事?
float** gradient(float* inputs, float* kernels, float* grads, npy_intp* input_dims, npy_intp* kernels_dims, npy_intp* output_dims)
float* g_inputs = new float[batch*h*w*ch_in];
for (int i = 0; i < batch*h*w*ch_in; i++) g_inputs[i] = 0;
float* g_kernels = new float[size*ch_out];
for (int i = 0; i < size*ch_out; i++) g_kernels[i] = 0;
float* ret[2] = g_inputs, g_kernels;
std::cout<<ret<<std::endl; //<---without this it doesn't work
return ret;
为了清楚起见,我省略了不相关的代码。
【问题讨论】:
new float[batch*h*w*ch_in];
这又是什么语言?你是说 C++ 吗?
【参考方案1】:
您正在返回一个指向具有自动生命周期的对象的指针。换句话说,您的函数返回一个悬空指针,即未定义行为。
虽然浮空蜥蜴是 UB 的罕见结果,但任何事情都可能发生,而且您观察到的症状与蜥蜴不同,很常见。
【讨论】:
那么当从函数返回时,程序是否会自动调用delete
定义的对象new
?
数组ret
不是用new
创建的。 (放入数组的两个指针是,它们没有被删除,所以你也有内存泄漏。)
ret
保留正确的地址。但是ret[0]
和ret[1]
不会。我该如何解决?
不要试图观察UB。躲开它。永远不要返回指向本地对象的指针。当然,悬空指针并没有改变,但是由于它指向的是真空,所以内容可以被重复用于其他目的。
那么我怎样才能使本地对象成为全局对象呢?以上是关于C 程序内存冲突取决于 std::cout (?)的主要内容,如果未能解决你的问题,请参考以下文章
使用参数创建时,std::thread 抛出访问冲突异常? [关闭]
使用带有 std::cout 的 volatile c-string [重复]