可能的内存管理问题或cygwin问题

时间:2013-04-25 22:50:47

标签: c memory-management cygwin

我有以下代码在ubuntu linux中按预期打印,但在windows中的cygwin中没有打印。但是,如果我摆脱了is_rotation函数中的free(t),那么它可以正常工作。我想知道我是否正在进行糟糕的内存管理,或者这是一个cygwin问题。为什么会这样。以及任何其他改善内存管理的建议。

以下是代码:

/**
* sub is a substring of str or not
**/
int is_substring(const char* str,const char* sub){
    const char* s1=str;
    const char*  s2=sub;
    int count=0;
    while(1){       
        if(*s2=='\0') return 1;
        else if(*s1=='\0') return 0;
        else if(*s1==*s2){
            count++;
            s2++;
        }   
        else{
            if(count!=0){
                s1-=count;
                count=0;
                s2=sub;
            }
        }
        s1++;
    }
    return 0;
}
/**
* s1 and s2 are rotations of eachother or not, given only the is_substring function.
**/
int is_rotation(const char* s1,const char* s2){
    int l1=strlen(s1);
    if(l1!=strlen(s2)) return 0;
    char* t=malloc(2*l1*sizeof(char));
    strcat(t,s1);
    strcat(t,s1);
    int r=is_substring(t,s2);
    free(t);
    return r;
}

/**
* USAGE: ./a.out string1 string2
**/
int main(int argc, char *argv[]){
    if(argc<3) return 1;
    printf("is_substring=%d",is_substring(argv[1],argv[2]));
    printf("\nis_rotation=%d",is_rotation(argv[1],argv[2]));
    return 0;
}

感谢您的帮助:)

2 个答案:

答案 0 :(得分:4)

问题出在第一次strcat()电话中。您应该用strcpy()替换它。

int is_rotation(const char* s1,const char* s2){
    int l1=strlen(s1);
    if(l1!=strlen(s2)) return 0;
    char* t=malloc(2*l1*sizeof(char) + 1);
    strcpy(t,s1); // initialize with strcpy() so we have a null in the string
    strcat(t,s1);
    int r=is_substring(t,s2);
    free(t);
    return r;
}

请注意malloc()不会初始化它正常分配的缓冲区。也许是ubuntu上的那个,但是保证。在cygwin中,缓冲区未初始化,因此strcat()是行走内存,在复制字符串之前寻找null ...这很可能超过了已分配缓冲区的末尾。

此外,你必须在缓冲区中添加一个额外的字符来保存最终字符串的空终止符...它是空终结符的l1 + 1的长度的2倍

答案 1 :(得分:1)

这是一个杀死你的堆栈的错误:

char* t=malloc(2*l1*sizeof(char));
strcat(t,s1);
strcat(t,s1);

第一个strcat将字符添加到某处...当您使用malloc时,t缓冲区的内容未知。你还需要一个字节为零。

char* t=malloc(2*l1+1); // (2*l1+1)*sizeof(char)
strcpy(t,s1);
strcat(t,s1);