简体   繁体   English

使用 realloc 连接字符串

[英]Using realloc to concat strings

I'm trying to concat two strings, supposing the "dest" string hasn't enough space to add another one, so I'm using dynamic arrays to solve it.我试图连接两个字符串,假设“dest”字符串没有足够的空间来添加另一个字符串,所以我使用动态数组来解决它。

The problem is a mremap_chunk error when trying to compile the code.问题是尝试编译代码时出现mremap_chunk错误。

I don't know what I'm missing since the realloc call has all the right params place in.我不知道我错过了什么,因为 realloc 调用包含了所有正确的参数。


Error:错误:

malloc.c:2869: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed. 
Aborted (core dumped)

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

char *strcatt(char *s1, char *s2)
{
    int a = strlen(s1);
    int b = strlen(s2);
    int i, size_ab = a+b;

    s1 = (char *) realloc (s1, size_ab*sizeof(char));

    for(i=0; i<b; i++) {
        s1[i+a]=s2[i];
    }

    s1[size_ab]='\0';

    return s1;
}


int main()
{
    char s1[]="12345";
    char s2[]="qwerty";

    strcatt(s1,s2);
    printf("%s\n", s1);

    return 0;
}

First, you are treating non-heap memory as heap memory, don't do that.首先,您将非堆内存视为堆内存,不要这样做。

Second you're not including space for the terminator in the calculation.其次,您没有在计算中包含终止符的空间。

Here are some more points:这里还有一些要点:

  1. Don't name functions starting with str , that's a reserved name space.不要命名以str开头的函数,这是一个保留的命名空间。
  2. Buffer sizes should be size_t , not int .缓冲区大小应该是size_t ,而不是int
  3. Don't cast the return value of malloc() in C . 不要在 C 中转换malloc()的返回值
  4. Use memcpy() to copy blocks of memory when you know the size.当您知道大小时,使用memcpy()复制内存块。
  5. The "right hand side" strings should be const . “右手边”字符串应该是const
  6. Deal with the possibility of allocation error.处理分配错误的可能性。
  7. I consider it bad practice to scale by sizeof (char) , that's always 1.我认为按sizeof (char)缩放是不好的做法,它总是 1。

Here's how I would write it, assuming the same logic:下面是我将如何编写它,假设相同的逻辑:

char * my_strcatt(char *s1, const char *s2)
{
    const size_t a = strlen(s1);
    const size_t b = strlen(s2);
    const size_t size_ab = a + b + 1;

    s1 = realloc(s1, size_ab);

    memcpy(s1 + a, s2, b + 1);

    return s1;
}

You can not realloc or free a memory that is not allocated with a call to malloc or is not NULL .你不能reallocfree不与呼叫分配到内存malloc或不是NULL

From section 7.22.3.5.来自第7.22.3.5 The realloc function in C11 draft C11 草案中的 realloc 函数

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. realloc函数释放ptr指向的旧对象,并返回一个指向size由 size 指定的新对象的指针。 The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes.新对象的内容应与解除分配前的旧对象的内容相同,直至新旧大小中较小的一个。 Any bytes in the new object beyond the size of the old object have indeterminate values.新对象中超出旧对象大小的任何字节都具有不确定的值。

So, s1 = (char *) realloc (s1, size_ab*sizeof(char));所以, s1 = (char *) realloc (s1, size_ab*sizeof(char)); is plainly wrong for your inputs (automatic arrays), never do that.您的输入(自动数组)显然是错误的,永远不要这样做。

And then there are many more problems which can be fixed with some help from a debugger.然后还有更多问题可以在调试器的帮助下修复。

The clang debugger gives a very clear error description: clang调试器给出了非常明确的错误描述:

malloc:  error for object 0x7fff6fbb16d6: pointer being realloc'd was not allocated
 set a breakpoint in malloc_error_break to debug

Both of your arrays are initialized as string literals.你的两个数组都被初始化为字符串文字。 Further on, your function tries to modify a string literal by reallocing it, which is wrong by C standard because you can't reallocate what you haven't allocated, and then copying the members of the second string literal to the "object" you intended to modify by misusing realloc() on a string literal.此外,您的函数尝试通过重新分配来修改字符串文字,这在 C 标准中是错误的,因为您无法重新分配尚未分配的内容,然后将第二个字符串文字的成员复制到您的“对象”旨在通过在字符串文字上滥用realloc()进行修改。

The code would work if you had dynamically defined a third string in which you would have summed the contents of both:如果您动态定义了第三个字符串,您将在其中对两者的内容求和,则该代码将起作用:

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

char *mystrcatt(char *s1, char *s2)
{
    int a = strlen(s1);
    int b = strlen(s2);
    int i, size_ab = a+b;

    char *s3 = malloc (size_ab*sizeof(char)); //sizeof(char) is always 1

    for(i=0; i<a; i++) { //inefficient
        (s3[i])=s1[i];
    }    

    for(i=0; i<b; i++) { //inefficient
        (s3[i+a])=s2[i];
    }

    s3[size_ab]='\0';

    return s3;
}


int main()
{
    char s1[]="12345";
    char s2[]="qwerty";
    char *s3 = mystrcatt(s1,s2);    
    printf("%s\n", s3);
    free(s3);
    return 0;
}

Please, also note that you don't cast the return of malloc() in C.请注意, 不要在 C 中转换malloc()的返回值。

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

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