尝试将 link 两个字符串放在一起时缓冲区溢出,为什么会出现此错误?

buffer overrun while trying to link two strings together, why do I have this error?

(在 C 中,使用 visual studio 2022 预览版),我必须编写一个程序,将 link 两个字符串放在一起。这是我所做的:

  1. 我写了两个for循环来计算第一个字符串和第二个字符串的字符数 字符串,

  2. 我检查了(在 link 函数内部,指针是否为空(第一个和第二个)。如果它们为空,则“return NULL”。

  3. 我创建了“char *result”。这是一个新字符串,这是要 returned 的字符串。我分配了足够的内存来存储 nprime、nscond 和另外 1 个字符(零终止符)。我使用了 malloc。

  4. 然后,我检查了结果是否为空。如果它为空,则“return NULL”。

  5. 然后,我写了 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 没有足够的空间容纳您实际需要的字符。