字符串附加功能不起作用

时间:2015-02-02 06:16:22

标签: c string memory-management

我尝试创建一个可以轻松附加两个字符串的函数。源字符串必须先前动态分配。我使用了我的知识,但这导致了ub和任何类型的泄漏。


void strapp (char *source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage);

    source_offset = realloc(source_offset, strlen(source_offset) + appendage_size);
    sprintf( &source_offset[position], "%s%s", appendage, source_offset + (position + appendage_size) );
}

我做错了什么?

6 个答案:

答案 0 :(得分:1)

source_offset + (position + appendage_size)有些奇怪。您似乎尝试使用第一个字符串复制第一个字符串中的第一个字符串的子字符串来连接第二个字符串。

source_offset + (position + appendage_size)是从offset position+appendage_size开始的源字符串的后缀,这是无意义的,因为它超过了源字符串的结尾......

你可能想要这样的东西吗? 如果你想连接两个字符串,那么以下是正确的:

size_t appendage_size = strlen(appendage);
source_offset = realloc(source_offset, position + appendage_size + 1);
sprintf( &source_offset[position], "%s", appendage );

appendage开始,将source_offset追加到position

现在,如果你想在中间插入appendage,这可能会有点棘手:

size_t appendage_size = strlen(appendage);
char *result = malloc(strlen(source_offset) + appendage_size + 1);
char cut = source_offset[position];
source_offset[position] = '\0';
sprintf( result, "%s%s%c%s", source_offset,appendage,cut,source_offset+position+1);
// do hat you want with result

请注意realloc可能会更改初始内存的基址,因此您无法执行此类操作,因为参数值source_offset将仅在本地更改。

答案 1 :(得分:0)

size_t appendage_size = strlen(appendage) + 1; /* To hold a \0 character */

分配的新数组应该能够在每个字符串中保存两个空字符

strlen(string) + 1

答案 2 :(得分:0)

如果你想修复你的功能,试试这个:

void strapp (char **source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage);

    *source_offset = (char*)realloc(*source_offset, strlen(*source_offset) + appendage_size);
    sprintf( *source_offset + position, "%s%s", appendage, *source_offset + (position + appendage_size) );
}

并将其称为strapp(&str, 10, "INSERTION"); // &str - pointer to pointer

问题在于:当您发送指向函数的指针时,您可以更改此指针指向的数据,但不能更改指针,因此在函数内部进行的内存分配会执行初始字符串的mot更改地址。

答案 3 :(得分:0)

实际上你的coes不会将字符串B附加到字符串A,它会将字符串B附加到字符串A的位置n以及字符串A,其中字符串A的内存偏移量为

char *
strapp(char *dest, const char *src)
{
    size_t i,j;
    for (i = 0; dest[i] != '\0'; i++)
        ;
    for (j = 0; src[j] != '\0'; j++)
        dest[i+j] = src[j];
    dest[i+j] = '\0';
    return dest;
}

上面的代码将字符串B附加到字符串A并返回指向字符串a A;

的指针
char* strapp (char *source_offset, const char *appendage, int position)
{
    char* temp = NULL:
    size_t appendage_size = strlen(appendage);
    if (( temp = realloc(source_offset, strlen(source_offset) + appendage_size + 1)) == NULL )
        return NULL;
    else
        source_offset = temp;
    sprintf( &source_offset[position], "%s", appendage);
    return source_offset;
}

答案 4 :(得分:0)

因为我被要求提供功能使用和输出的示例。我将这段代码转换为可编辑的东西,它的工作方式与预期的一样。

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

void strapp (char *source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage) + 1;

    source_offset = realloc(source_offset, strlen(source_offset) + appendage_size);
    sprintf( &source_offset[position], "%s%s", appendage, source_offset + (position + appendage_size) );
}

int main(void)
{
    char *str1 = malloc(11 + 1);

    sprintf(str1, "Hello World");

    strapp(str1, 4, " Horrible ");

    printf(str1);
    free(str1);

    return 0;
}

输出:Hell Horrible

答案 5 :(得分:0)

我在调查时发现问题的部分解决方法。 如果我将子字符串添加到源字符串的位置,如:

sprintf(&source[4], "new");

源字符串将由"new"终止,其余字符串将不会显示。 但是如果我声明子串"new"并使用 memcpy(&str1[4], appendage, 3);它完成了这项工作。


在那里,这是工作职能:

void strapp (char *source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage) + 1;
    char copy[strlen(source_offset) + 1];

    strcpy(copy, source_offset);

    source_offset = realloc(source_offset, strlen(source_offset) + appendage_size);
    memcpy(&source_offset[position], appendage, strlen(appendage));
    sprintf(&source_offset[position + strlen(appendage)], &copy[position]);
}