尝试将 link 两个字符串放在一起时缓冲区溢出,为什么会出现此错误?
buffer overrun while trying to link two strings together, why do I have this error?
(在 C 中,使用 visual studio 2022 预览版),我必须编写一个程序,将 link 两个字符串放在一起。这是我所做的:
我写了两个for循环来计算第一个字符串和第二个字符串的字符数
字符串,
我检查了(在 link 函数内部,指针是否为空(第一个和第二个)。如果它们为空,则“return NULL”。
我创建了“char *result”。这是一个新字符串,这是要 returned 的字符串。我分配了足够的内存来存储 nprime、nscond 和另外 1 个字符(零终止符)。我使用了 malloc。
然后,我检查了结果是否为空。如果它为空,则“return NULL”。
然后,我写了 2 个 for 循环来执行第一个字符串和第二个字符串之间的 linking。在这里我得到了一个编译器警告(因为我认为它是在编译时而不是在调试时)。缓冲区溢出,可写大小为
"nprime+nscond+1" 但可能会写入 2 个字节。
我的理论是该程序试图在结果数组之外写入,因此可能会丢失数据,我试图编辑我的代码,因此我写了“nprime + nsecond + 2”,但它不起作用,它一直向我显示相同的缓冲区溢出错误。
#include <stdlib.h>
char* link( const char* first, const char* second) {
size_t nprime = 0;
size_t nsecond = 0;
if (first == NULL) {
return NULL;
}
if (second == NULL) {
return NULL;
}
for (size_t i = 0; first[i] < '[=11=]'; i++) {
nprime++;
}
for (size_t i = 0; second[i] < '[=11=]'; i++) {
nsecond++;
}
char* result = malloc(nprime + nsecond + 1);
if (result == NULL) {
return NULL;
}
for (size_t i = 0; i < nprime; i++) {
result[i] = first[i];
}
for (size_t i = 0; i < nsecond; i++) {
result[nprime + i] = second[i];
}
result[nprime + nsecond] = 0;
return result;
}
这是主要的:
int main(void) {
char s1[] = "this is a general string ";
char s2[] = "this is a general test.";
char* s;
s = link(s1, s2);
return 0;
}
警告是由于您在前 2 个 for 循环中定义的错误条件。正确的循环应该如下:
for (size_t i = 0; first[i] != '[=10=]'; i++) {
nprime++;
}
for (size_t i = 0; second[i] != '[=10=]'; i++) {
nsecond++;
}
根据您定义的条件(即 first[i] < '[=11=]'
),您只是计算给定字符串中有多少字符的 ASCII 代码低于 [=12=]
的 ASCII 代码,并尽快退出循环当您发现不满足此类条件的字符时。
由于 '[=13=]'
的 ASCII 值为 0,您的 nprime 和 nsecond 永远不会增加,导致 malloc 没有足够的空间容纳您实际需要的字符。
(在 C 中,使用 visual studio 2022 预览版),我必须编写一个程序,将 link 两个字符串放在一起。这是我所做的:
我写了两个for循环来计算第一个字符串和第二个字符串的字符数 字符串,
我检查了(在 link 函数内部,指针是否为空(第一个和第二个)。如果它们为空,则“return NULL”。
我创建了“char *result”。这是一个新字符串,这是要 returned 的字符串。我分配了足够的内存来存储 nprime、nscond 和另外 1 个字符(零终止符)。我使用了 malloc。
然后,我检查了结果是否为空。如果它为空,则“return NULL”。
然后,我写了 2 个 for 循环来执行第一个字符串和第二个字符串之间的 linking。在这里我得到了一个编译器警告(因为我认为它是在编译时而不是在调试时)。缓冲区溢出,可写大小为 "nprime+nscond+1" 但可能会写入 2 个字节。 我的理论是该程序试图在结果数组之外写入,因此可能会丢失数据,我试图编辑我的代码,因此我写了“nprime + nsecond + 2”,但它不起作用,它一直向我显示相同的缓冲区溢出错误。
#include <stdlib.h> char* link( const char* first, const char* second) { size_t nprime = 0; size_t nsecond = 0; if (first == NULL) { return NULL; } if (second == NULL) { return NULL; } for (size_t i = 0; first[i] < '[=11=]'; i++) { nprime++; } for (size_t i = 0; second[i] < '[=11=]'; i++) { nsecond++; } char* result = malloc(nprime + nsecond + 1); if (result == NULL) { return NULL; } for (size_t i = 0; i < nprime; i++) { result[i] = first[i]; } for (size_t i = 0; i < nsecond; i++) { result[nprime + i] = second[i]; } result[nprime + nsecond] = 0; return result; }
这是主要的:
int main(void) {
char s1[] = "this is a general string ";
char s2[] = "this is a general test.";
char* s;
s = link(s1, s2);
return 0;
}
警告是由于您在前 2 个 for 循环中定义的错误条件。正确的循环应该如下:
for (size_t i = 0; first[i] != '[=10=]'; i++) {
nprime++;
}
for (size_t i = 0; second[i] != '[=10=]'; i++) {
nsecond++;
}
根据您定义的条件(即 first[i] < '[=11=]'
),您只是计算给定字符串中有多少字符的 ASCII 代码低于 [=12=]
的 ASCII 代码,并尽快退出循环当您发现不满足此类条件的字符时。
由于 '[=13=]'
的 ASCII 值为 0,您的 nprime 和 nsecond 永远不会增加,导致 malloc 没有足够的空间容纳您实际需要的字符。