c++ - 返回对象时清除内存指针

标签 c++

这让我崩溃了一段时间。我确定这是有原因的:

chain operator+(chain c)
{
    chain<Object> result;
    for (int i = 0; i < length(); i++)
    {
        result.insert(*(Object*)(memory+(i*sizeof(Object))));
    }
    for (int i = 0; i < c.length(); i++)
    {
        result.insert(c[i]);
    }
    for (int i = 0; i < result.length(); i++) // This for loop successfully shows all objects in result
    {
        cout << result[i];
    }
    return result;
}

返回值时,即:

chain<int> a;
cin >> a; // enter "5 6 7 8"
chain<int> b;
cin >> b; // enter "9 10 11 12"
chain <int> c = a+b;

cout << c; // Returns "0 0 7 8 9 10 11 12"

前两个数字总是0。我不明白为什么。这只有在将两条链加在一起时才会发生;如果我计算出 a 或 b,我会得到所有的值。

如果有人有任何信息可以分享,我将不胜感激:)

编辑**

完整源代码

#ifndef CHAIN_H
#define CHAIN_H

#include <iostream>
#include <stdlib.h>

using namespace std;

template <class Object>
class chain
{
    public:
            chain(){
                    memorySize = 8;
                    memory = calloc(memorySize, sizeof(Object));
                    count = 0;
            }
            chain(Object item){
                    memorySize = 8;
                    memory = calloc(memorySize, sizeof(Object));
                    count = 0;
                    insert(item);
            }
            chain(chain & original){
                    memorySize = 8;
                    memory = calloc(memorySize, sizeof(Object));
                    count = 0;
                    for (int i = 0; i < original.length(); i++)
                    {
                            insert(original[i]);
                    }
            }
            ~chain(){
                    free(memory);
            }
                chain operator+(chain c){
                    chain<Object> result;
                    for (int i = 0; i < length(); i++)
                    {
                            result.insert(this->operator[](i));
                    }
                    for (int i = 0; i < c.length(); i++)
                    {
                            result.insert(c[i]);
                    }
                    for (int i = 0; i < result.length(); i++)
                    {
                            cout << result[i];
                    }
                    return result;
            }
            Object & operator[](int pos){
                    return *(Object*)(memory+(pos*sizeof(Object)));
            }
            int length(){
                    return count;
            }
            void insert(Object item){
                    if (count == memorySize)
                    {
                            doubleMemory();
                    }
                    this->operator[](count) = item;
                    count++;
            }
    private:
            int count;
            int memorySize;
            void * memory;
            void doubleMemory(){
                    memorySize *= 2;
                    memory = realloc(memory, (memorySize*sizeof(Object)));
            }

};
template <class Object>
ostream& operator<<(ostream& out, chain<Object>& c){
    for (int i = 0; i < c.length(); i++)
    {
            out << c[i] << " ";
    }
}
template <class Object>
istream& operator>>(istream& in, chain<Object>& c){
    char ch;
    int number = 0;
    int sign;
    while(ch != '\n')
    {
            ch = in.get();
            if (ch == '-')
            {
                    sign = 1;
            }
            else if (ch >= '0' && ch <= '9')
            {
                    number *= 10;
                    number += (ch-48);
            }
            else if (ch == ' ' || ch == '\n')
            {
                    number = sign == 1? 0 - number : number;
                    c.insert(number);
                    sign = 0;
                    number = 0;
            }
    }
}
#endif

这是我正在测试的代码:

#include "chain.h"

using namespace std;

int main(){

    chain<int> a, b, c;
    chain<int> d(10);
    chain<int> e(d);
    cin >> a;
    cout << endl;
    cout << endl;
    c = a+d;
    cout << c;
}

~

最佳答案

您显示的代码不是问题所在。真正的问题可能在 chain 的复制构造函数或析构函数中——也可能在 insert 方法中(或者,在 C++11 上,在移动构造函数中) .

(它也可能在 Object 的复制构造函数中,但我认为这不太可能。)


编辑:天哪。不要用 C++ 编写此类代码。左边、右边和中间都不安全。只要 Object 是一个 POD,你应该没问题,但如果不是,这段代码会产生未定义的行为。特别是,它不会为您存储在链中的对象调用正确的构造函数和析构函数。

此外,您的复制构造函数应该采用 chain const& 类型的参数,因为您不会修改传递的 chain。这反过来又要求您通过提供 operator [] 的适当 const 重载来使您的类 const 正确。

最后也是最明显的,你违反了三原则,因为你没有为你的实现operator =。尝试将一个 chain 分配给另一个将导致双重释放。

通常避免使用 callocfree 并改用标准容器,或者,如果这不是一个选项,则使用 new[] 加上一个像boost::shared_array这样的智能指针管理内存(但不要使用delete[])。

还有一点,永远不要在头文件中使用using namespace,它会污染命名空间并导致在最奇怪的地方发生名称冲突。

关于c++ - 返回对象时清除内存指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12365985/

相关文章:

c++ - 如何改进基于sse的矩阵乘法

c++ - 使用 GDB 调试时段错误消失

c++ - 免注册 COM 的 list 中需要哪些标签?

c++ - std::unique_lock<std::mutex> 禁止dll卸载

c++ - 在 OpenCV 中通过 cartToPolar 放置点 vector

c++ - 当 c++ xx 获得批准时,命名空间 tr1 会发生什么变化?

c++ - DWORD 在 LPVOID 上的类型转换返回什么?

c++ - Visual C++ 2010 - 转换 10 GB BYTE 数组的最快方法?

使用引用的 C++ 错误

c++ - 不同编译器的打包结构大小和继承