保持我的字符范围,并处理它

问题描述:

我有一个函数,将相对路径(例如“log \ crash.txt”)转换为完整路径(例如“E:\ Program \ log \ crash.txt”) 。该功能是:保持我的字符范围,并处理它

string_t GetAbsPath(string_t relPath) 
{ 
    char abs[1024]; 

    //Get the working directory 
    GetCurrentDirectory(1024, abs); 

#pragma warning(disable:4996) 
    //Add a slash and content folder 
    memcpy(&abs, strcat(abs, "\\content\\"), 1024); 
    //Append it to the relative path 
    memcpy(&abs, strcat(abs, relPath.c_str()), 1024); 
#pragma warning(default:4996) 

    return abs; 
} 

string_t是一类我写的,它基本上为const char*的包装。我的问题是,(我有点期待这个......)是,当函数返回时,abs超出范围,并且获取返回值的string_t现在为空/垃圾。在这样的情况下,我通常会使用memcpy将它复制到一个不会超出范围的指针。但是问题在于,那个指针(这将是string_t中的const char*)将需要为delete[]'d。 string_t没有析构函数开始。我可以写一个delete[]它在那里,但posses另一个问题:

如果我创建一个string_t这样的:

string_t crash = "New[] isn't called! Ahh!"; 

当我去delete[]它在析构函数,程序会崩溃,因为新[]从未被调用过。

我可以delete[]在调用GetAbsPath的功能const char*,就像这样:

void LoadModel(string_t relPath) 
{ 
    string_t fullPath = GetAbsPath(relPath); 
    . . . 
    delete[] fullPath.c_str(); 
} 

但我知道,如果我回来的代码后,我会像“这是为什么delete[]有“,或者在不需要时添加它......而且指针是,那里有很多错误空间。

我该怎么做才能保持该范围内的字符(我猜这只能用指针来完成),并确保分配的内存得到清理?必须有一种方法,因为std :: string保持一切清洁,并且具有连接等功能,这是我的string_t甚至没有的功能。我感谢所有帮助这里,因为我不知所措......

+2

也许'string_t'不是用作返回类型的正确类型,正是因为它没有必要的析构函数。它看起来像一种“单向”类型;你可以将它传递给一个函数,但如果必须分配要传回的内存,则不能可靠地将其返回。如果要传回的数据本身是不可变的,那么你可以使用'string_t'确定。让函数以某种形式或形式返回一个'std :: string'('const std :: string&'?)。 –

+1

摆脱'memcpy's。它们被破坏('memcpy'不能处理重叠的输入和输出)。另外,不需要将数据复制到原来的位置。只需调用'strcat'来追加到一个字符串。 –

+0

@JonathanLeffler你说的话给了我一个主意。将类型总是使用'new []'是否是一个好主意,因此总是使用'delete []'?我的意思是,在构造函数中,如果使用了'string_t(“Foobar”)',它会为字符串(6个字符+终结符)分配空间(使用'new []')并复制该字符串(“Foobar” ) 进去。这样,总是需要调用delete []'。 – smoth190

你有三种选择:

1)决定string_t将永远拥有它指向字符串,这将是负责释放它。让构造函数分配/复制。

2)决定string_t将永远不拥有它指向的字符串,并且代码调用它将始终负责在必要时释放它。

3)决定string_t将支持这两种型号,并需要一个标志来决定是否在其析构函数中调用free[]。调用代码必须告知string_t是否分配/复制或是否仅存储指针。请致电rule of three。或者更好的是,只需使用std::string,它始终采用选项1,因此您可以使用它而不用担心。

+0

我刚刚意识到你在选择1中所说的话,你的回答让我感到安全。谢谢! – smoth190