如何在 C++ 中为 char *array 安全地重新分配内存(用于 CustomString 类)

Posted

技术标签:

【中文标题】如何在 C++ 中为 char *array 安全地重新分配内存(用于 CustomString 类)【英文标题】:how to safely reallocate memory in C++ for char *array (it's for CustomString class) 【发布时间】:2017-11-17 04:22:22 【问题描述】:

我认为我的老师主要是在告诉我们分配内存的错误方法......

但我不完全确定将更多内存安全地重新分配给指针的正确方法是什么。在我看来重新分配内存的目的是因为旧的内存分配不够大(例如,在执行前缀增量运算符重载时,例如附加字符'X',大概你需要足够大的新分配来适应最终结果?)

问题:

    1234563递增运算符重载)?

    我现有的代码在前缀增量运算符重载中是否存在内存泄漏?

    在 Windows 上的 Visual Studio 2017 中编码 C++ 时如何发现内存泄漏?

关于我的项目的基本信息: 目标是创建您自己的 CustomString 类,并将 char*pointer 作为 CustomString 类的私有实例变量。

我已经创建了自己的 CustomString 类,我应该做一些运算符重载,例如加法运算符、前缀增量运算符。

加法运算符的主要目的当然是字符串连接。使用前缀递增运算符,您只需在末尾添加一个字符“X”。

我可以在我现有代码的定义下方发布。

自定义字符串.h

#pragma once
#include <iostream>
#include <string.h>
using namespace std;

class CustomString

    friend ostream &operator<<(ostream &out, const CustomString &reference);//OUTPUT OPERATOR OVERLOADED as friend function

public:
    static const int MaxSize = 10;//classwide constant
    static int getNumberOfCustomStrings();

    CustomString(const char *namepointer="");// constructor
    //CustomString(char * pointer);//constructor w/parameters
    ~CustomString();//destructor
    CustomString(const CustomString &stringref);    //copy constructor w/dynamic datamember
    operator const char*() const; // IMPLICIT CONVERSION operator overloaded


     CustomString operator+( const CustomString &addedpart) const;  // PLUS OPERATOR OVERLOADED implemented as string concatenate
    const CustomString& operator=(const CustomString &ref); //ASSIGNMENT OPERATOR OVERLOADED works for dynamic strings as well
    const CustomString &operator++();//PREINCREMENT OPERATOR OVERLOADED
    CustomString operator++(int);//POSTINCREMENT OPERATOR OVERLOADEd
    char& operator[](int i) const;// INDEXING OPERATOR OVERLOADED

private:
    char * c_string;
    void list();
    static int numberOfCustomStrings;
;

来自CustomString.cpp,这里是前缀增量代码段

const CustomString & CustomString::operator++()// PREFIX INCREMENT OVERLOADED, adds an 'X' character into the dynamic instance variable(char*c_string)


    if (  strlen(c_string) == (MaxSize-1)   ) 
        cout << "error cannot increment any further" << endl;
        return *this;
    
    else 
        int oldlength = strlen(c_string) +1;
        char*newdata;
        newdata = new char[ oldlength+1  ]; //it has to be one char bigger allocation bevause one "X" soon will be added
        strcpy_s(newdata, oldlength+1, c_string);//put the old data into new allocation as the baseword
        newdata[oldlength-1] = 'X';
        newdata[oldlength] = '\0';
        delete c_string;//free the old memory
        c_string = newdata; //give  the new allocation to the dynamic instance variable
        return *this;

    


我相信我已经正确地做了析构函数、构造函数和复制构造函数,但我也可以给出他们的代码

CustomString.cpp 的构造函数

CustomString::CustomString(const char *pointer)// constructor

    if(   (strlen(pointer)+1) <=MaxSize   )
    c_string = new char[strlen(pointer) + 1];
    strcpy_s(c_string, (strlen(pointer) + 1), pointer);
    numberOfCustomStrings++;
    
    else 
        c_string = new char[MaxSize];
        //printf("char at last index was == %c \n", c_string[MaxSize-1]);
        int j = 0;
        for (j = 0; j <= (MaxSize-2); j++) 
            c_string[j] = pointer[j];
        
        //printf("the last truechar was %c \n",pointer[MaxSize-2]);
        c_string[MaxSize - 1] = '\0';
        //printf("the last char was %c\n", pointer[MaxSize-1]);
        numberOfCustomStrings++;
    


这是来自 CustomString.cpp 的复制构造函数

CustomString::CustomString(const CustomString &ref)     //copy-constructor w/dynamic data member.

    c_string = new char[strlen(ref.c_string) + 1];  
    strcpy_s(c_string, strlen(ref.c_string) + 1, ref.c_string);
    numberOfCustomStrings++;

这是来自 CustomString.cpp 的析构函数

CustomString::~CustomString()   // destructor

    delete c_string;  
    cout << "destructor called!" << endl;
    numberOfCustomStrings--;

【问题讨论】:

首先,你分配内存为char* newdata= new char[somesize];,释放为delete c_string,这是内存泄漏。使用delete[] c_string释放所有数组。 感谢您的回答!我向老师问过同样的事情,但他显然给了我关于使用数组删除运算符的错误建议。 delete c_string 只释放第一个元素的内存,delete[] c_string 释放数组的内存。 cplusplus.com/doc/tutorial/dynamic 除了缺少delete[]操作符之外,你有没有发现其他故障?对不起,我现在对这整件事真的很偏执。 如我所见,就在您使用delete c_string 时。注意您在哪里保留 (new) 以及何时释放 (delete)。请记住这条规则:保留、使用和免费。 【参考方案1】:

代码:

char *a = new char;
delete a;

char *array = new char[100];
delete [] array;

您可以使用视觉检漏仪来定位线路

【讨论】:

以上是关于如何在 C++ 中为 char *array 安全地重新分配内存(用于 CustomString 类)的主要内容,如果未能解决你的问题,请参考以下文章

如何将字符串数组转换为 Char * 数组 c++

在 Eclipse 中为 C++ 设置 GTKmm

如何在C中为char**动态分配内存

如何在 C++ CLR 中将数组<System::Byte> 转换为 char*?

将目录中的文件名添加到 char* 数组。 C++

如何在 foreach 循环中为 char 变量赋值? C#