繁体   English   中英

在 C 语言中出现这些错误意味着什么?

[英]what does it mean to have these kind of errors in C?

这是我的解决方案

#include <stdlib.h>
#include <string.h>

char* deletemultiple(const char* str) {
    if (str == NULL) {
        return NULL; 
    }
    size_t length = strlen(str); 
    if (length == 0) {
        return str; 
    }
    length = length + 1u; 
    char* s = malloc(length); 
    if (s == NULL) {
        return NULL; 
    }  
    size_t j = 0; 
    for (size_t i = 0; s[i] != 0; i++) {
        if (str[i] != str[i+1]) {
            s[j++] = str[i]; 
        }
    }
    s = realloc(s, j+1); 
    if (s == NULL) {
        return NULL; 
    }

    return s; 
}



 int main(void) {
    char str[] = ""; 
    char* s = deletemultiple(str); 

    free(s); 
    return 0; 
} 

这是一个删除多个字符(即相邻字符)并返回没有多个相邻字符的新分配字符串的程序。 此解决方案仅适用于长度为 != 0 的字符串; 但是如果字符串是“”(即一个空字符串),当我释放内存时,我会遇到阻止程序的错误。 (即执行了断点指令(__debugbreak() 语句或类似调用))。

此外,我有 2 个警告:一个警告提醒我“realloc 可能返回一个空指针”,但我已经知道这一点,事实上我已经使用了一个 if 块来检查它是否为空。

另一个警告是关于“从 s 读取无效数据,它与这个 for-loop 块有关:

 for (size_t i = 0; s[i] != 0; i++) {
        if (str[i] != str[i+1]) {
            s[j++] = str[i]; 
        }
    }

有人可以解释这些错误/警告的含义,以及如何解决它们吗? 在类似的练习中,如果我再次出现这些错误,我该怎么办?

如果长度为零,则您的函数将返回其参数,因此您的代码与以下内容相同:

int main(void) {
    char str[] = ""; 
    char* s = str; 
    free(s);  /* ERROR: This is wrong!! */
    return 0; 
} 

但你不能free(str) ,因为str没有分配malloc

只需删除针对长度为零的特殊情况检查,并修复您的错误,以便分配length + 1为空终止符留出空间。

如果您传递了一个空字符串,则返回此空字符串

char* deletemultiple(const char* str) {
    if (str == NULL) {
        return NULL; 
    }
    size_t length = strlen(str); 
    if (length == 0) {
        return str; 
    }
    //...

所以你可能不会像你正在做的那样为这样的指针free调用函数

char* s = deletemultiple(str); 

free(s);

就是功能接口坏了。 您需要返回一个动态分配的空字符串。

动态分配的数组s不包含字符串,因为您忘记在它后面附加零终止字符'\0'

如果内存重新分配不成功

s = realloc(s, j+1); 
if (s == NULL) {
    return NULL; 
}

然后该函数会产生内存泄漏,因为在这种情况下不会释放的先前分配的内存的地址将由于重新分配指针s而丢失。 例如,您需要使用中间指针

char *tmp = realloc(s, j+1); 
if (tmp == NULL) {
    free( s );
    return NULL; 
}

两次分配内存的方法是不安全的。 也不需要检查str是否等于NULL

if (str == NULL) {
    return NULL; 
}

字符串函数支持约定,根据该约定,如果用户传递空指针,则函数具有未定义的行为。

该功能可以如下面的演示程序所示,例如下面的方式。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char * delete_multiple( const char *s ) 
{
    size_t n = strlen( s );

    for ( const char *p = s; *p++; )
    {
        if ( *p == *( p - 1 ) ) --n;
    }

    char *result = malloc( n + 1 );

    if ( result != NULL )
    {
        char *p = result;
        for ( *p = *s; *s++; )
        {
            if ( *s != *p ) *++p = *s;
        }
    }

    return result;
}

int main( void )
{
    char *p = delete_multiple( "" );

    printf( "\"%s\"\n", p );
    free( p );

    p = delete_multiple( "a" );

    printf( "\"%s\"\n", p );
    free( p );
    

    p = delete_multiple( "aa" );

    printf( "\"%s\"\n", p );
    free( p );
    
    p = delete_multiple( "aaa" );

    printf( "\"%s\"\n", p );
    free( p );

    p = delete_multiple( "abaca" );

    printf( "\"%s\"\n", p );
    free( p );
}

程序输出为

""
"a"
"a"
"a"
"abaca"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM