2016-01-23 43 views
0

我最后的功能不起作用。该函数将一个文字字符串附加到C字符串中。它检查C字符串中是否有足够的空间将字符串附加到它。如果没有足够的空间,则C字符串长度必须扩展为(字符串长度+ C字符串长度)大小的两倍。然后它可以将字符串附加到C字符串。在运行程序并输入一个文本字符串后,显示第一个输出语句,然后在我收到“抛出std :: bad_alloc实例后调用terminate”的错误并且程序停止工作后。所有其他功能在此追加功能之前工作。有没有办法修复最后一个附加函数的工作?如何解决将字符串附加到C字符串的错误?

int main() 
{ 
char* s1 = assign();    
char* s2 = assign(" C++ "); 



char* s3 = add(s1, s2); 
cout << "length of \"" << s3 << "\" is " << strlen(s3) << endl; 


append(s3, "programming language"); // This function doesn't work 
cout << "length of \"" << s3 << "\" is " << strlen(s3) << endl; 

return 0; 
} 


char* assign() 
{ 
const int SIZE = 100; 
char temp[SIZE]; 
int length; 
int twicelen; 

cout << "Enter a text string which will be used to append literal strings to it: "; 
cin.getline(temp, SIZE); 
length = strlen(temp); 
twicelen = length * 2; 


char* newCstring = new char[twicelen]; 
strcpy(newCstring, temp); 

return newCstring; 
} 



char* assign(string str) 
{ 
int len = strlen(str.c_str()); 
int newlen = len * 2; 
char* newStr = new char[newlen]; 

strcpy(newStr, str.c_str());; 

return newStr; 
} 


char* add(char* s1, char* s2) 
{ 
strcat(s1, s2); 
return s1; 
} 


void append(char* s3, string literalStr) // Every function before this works and this is where the program gives an error and closes. 
{ 


if (sizeof(s3) < (strlen(s3) + strlen(literalStr.c_str()) + 1)) 
{ 
    int expandLength = (strlen(s3) + strlen(literalStr.c_str())) * 2; 
    char* s3 = new char[expandLength]; 
    strcat(s3, literalStr.c_str()); 

} 
else 
    strcat(s3, literalStr.c_str()); 

} 
+2

为什么不使用std :: string? –

+2

你在学习指针吗?否则,你应该使用'std :: string'。 –

+3

添加一些输出以显示'sizeof(s3)'的值。这不是你想象的那样。 –

回答

1

问题1:

你实现add()可能会导致缓冲区溢出:

这里就是你必须在主:

char* s1 = assign(); // here memory is allocated for the string you input   
char* s2 = assign(" C++ "); // here memory is allocated again 

char* s3 = add(s1, s2); // <==== ouch 

不幸的是,add()只是让一个strcat()没有确保目标字符串有足够的内存。从那时起,你处于UB的恐怖世界。任何事情都可能发生。例如,字符串的结尾null可能会丢失,导致strlen()找到一个巨大的长度,并在您尝试分配两次如此巨大的数字时导致内存不正常。

问题2:

append()功能本身是有缺陷的。

首先,sizeof(s3)是指针s3的大小,所以一个相当小的数字。这不是分配字节的大小。所以您很有可能会输入if区块(但出于错误原因)。

接下来,您将分配一个新的s3。问题在于函数中存储的s3的值对于函数是本地的。主要指针s3什么都不会发生,仍然指向原来的地方。

要纠正第二个问题,您需要通过引用传递指针。或者更改函数的签名以返回指针s3。在这种情况下,你会写在主:s3 = append (s3, ...);

+0

我需要使'append()'成为一个void函数并且不返回任何东西。为了纠正第二个问题,如果我想通过引用来传递指针,我该怎么做?我非常感谢你的帮助。 – Mark

+0

@好的!只需在参数声明中放入一个&before s3即可。 – Christophe

+0

它会看起来像这样:void append(char&s3,string literalStr)'?我试着用这种方式声明'void append(char *&s3,string literalStr)',这没有奏效。 – Mark