문제

해봤을 쓰는 문자열을 바꾸기능 C 에서 작동에 char *, 는 할당을 사용하여 malloc().그것은 조금 다르다는 점에서 찾을 수 있고 교체 문자열이 아닌 캐릭터에서 시작하는 문자열입니다.

그것의 사소하는 경우 검색 및 교체 문자열의 길이가 동일(또는 교체 문자열을 보다 짧은 문자열 검색),이는 충분한 공간이 할당됩니다.하려 하는 경우 사용 realloc(), 에,나는 오류를 알려주는 나에게 나 하고 있는 더블유-는 보이지 않는 어떻게 나 때문에,나는 단지 사용 realloc().

아마도 작은 코드에 도움이 될 것입니다:

void strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen - searchLen;
    char *find = input;

    while (find = strstr(find, search)) {

        if (delta > 0) {
            realloc(input, strlen(input) + delta);
            find = strstr(input, search);            
        }

        memmove(find + replaceLen, find + searchLen, strlen(input) - (find - input));
        memmove(find, replace, replaceLen);
    }
}

프로그램이 작동 될 때까지,도 realloc() 인스턴스에서는 교체된 문자열이 더 길어질 수 있보다 초기 문자열입니다.(이것은 여전히 작품의 종류,그것은 다 뱉어 오류뿐만 아니라 결과).

도움이 된다면,호출하는 코드는 다음과 같:

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

void strrep(char *input, char *search, char *replace);

int main(void) {
    char *input = malloc(81);

    while ((fgets(input, 81, stdin)) != NULL) {
        strrep(input, "Noel", "Christmas");
    }
}
도움이 되었습니까?

해결책

일반적으로,당신 하 무료 또는 realloc 에서 제공하는 사용자 버퍼입니다.당신이지도 모르고,어디로 가는지도 모릅 사용자에 할당된 공간(에서 당신의 모듈에서 또 다른 DLL)그래서 당신이 사용할 수 없습의 할당 함수에서 사용자 버퍼입니다.

제공하는 당신은 지금 할 수 없이 어떤 재할당 내에서 당신의 기능을 변경해야 합니다 행동이 조금 같은 단 하나의 보충,그래서 사용할 수 있는 계산 결과 문자열을 최대 길이 및 너를 제공하는 버퍼에 대해 충분히 이 하나를 교체 발생할 수 있습니다.

을 만들 수 있습니 다른 기능을 할 여러 개의 보충,하지만 당신이해야 할당 전체적인 공간에 대한 결과 문자열과 복사본을 사용자 입력 문자열입니다.다음을 제공해야 합 방법은 문자열을 삭제 당신이 할당됩니다.

결과:

void  strrep(char *input, char *search, char *replace);
char* strrepm(char *input, char *search, char *replace);
void  strrepmfree(char *input);

다른 팁

첫째,sorry I'm late 되어 있습니다.이 직접 대답이다.:)

으로 지적되어 왔을 때,realloc()를 호출할 수 있습니다 변경 포인터를 메모리 할당.이 경우,인수"라는 문자열"가 잘못되었습니다.는 경우에도 당신은 할당,변경의 범위를 한번 함수가 종료됩니다.

에 대답하 OP,realloc()포인터를 반환하는 새로 할당 메모리입니다.반환 값가 어딘가에 저장해야합니다.일반적으로,당신이 할 것이다:

data *foo = malloc(SIZE * sizeof(data));
data *bar = realloc(foo, NEWSIZE * sizeof(data));

/* Test bar for safety before blowing away foo */
if (bar != NULL)
{
   foo = bar;
   bar = NULL;
}
else
{
   fprintf(stderr, "Crap. Memory error.\n");
   free(foo);
   exit(-1);
}

로 TyBoer 지점,당신은 사람을 변경할 수 없습니다 포인터의 값을 전달에서 입력으로 이 함수입니다.할당할 수 있습니다 당신이 무엇을 원하지만,변경의 범위의 끝에서 기능이다.에서 다음과 같은 블록,"입력"되지 않을 수 있는 잘못된 포 일단 기능이 완료된:

void foobar(char *input, int newlength)
{
   /* Here, I ignore my own advice to save space. Check your return values! */
   input = realloc(input, newlength * sizeof(char));
}

표시하려고 이를 반환하여 새로운 포인터로 출력 기능이다.만약 당신이 그렇게 한다면,무거운 짐이에서 호출을 절대로 다시 사용하여 포인터 위해 사용되는 입력입니다.과 일치하는 경우에는 반환 값을,당신은 두 가지 포인터 같은 자리에만 호출할 필요가 무료()에 그들 중 하나입니다.일치하지 않을 경우,입력 포인터 이점을 기억지 않을 수 있는 소유하고 있는 과정입니다.참조 문제가 발생할 수 있습 segmentation fault.

당신이 사용할 수 있는 더블 포인터 입력을 위해,다음과 같다:

void foobar(char **input, int newlength)
{
   *input = realloc(*input, newlength * sizeof(char));
}

신되는 경우에는의 중복을 입력 포인터가 어딘가에,그 중복 여전히 유효하지 않을 수도 있습 now.

내가 생각하는 가장 깨끗한 솔루션을 사용하지 않 realloc()를 수정하려는 경우 이 함수 호출자의 입력이 있습니다.그냥 malloc()새로운 버퍼,반환하는 것,그리고 발신자는지 여부를 결정을 무료로 이전 텍스트입니다.이것은 혜택을 추가시키는 발신자의 유지 원래의 문자열!

다만에 진지 않았기 때문에 그것을 시도했지만 아직할 때 realloc 그것은 포인터를 반환하는 훨씬 다음과 같 malloc.기 때문에 realloc 이동할 수 있는 포인터 필요한 경우 가장 가능성이 운영에 잘못된 포인터를 하지 않는다면 다음과 같다:

input = realloc(input, strlen(input) + delta);

다른 누군가에게 사과는 늦은 파티에-두 개의 반합니다.오론,보내는 아주 많은 시간을하고 소프트웨어고 있습니다.

내가 관심있는 아무도 주석에서 명시적으로 메모리 누수가에서 원래 디자인 또는 오프-바이-중 오류가 있습니다.고 그것을 관찰하는 메모리 누수가 말하는 나에게 이유를 정확하게 당신이 점점 더블 무료러(기 때문에,정확한 수,당신은 당신을 자유롭게 동일한 메모리에 여러 번을-그리고 당신은 후 이렇게 짓밟을 통해 이 메모리를 해제).

을 수행하기 전에 분석을,나는 것에 동의 말하는 사람들의 인터페이스보다 적은 별;그러나,당신이 처리하는 메모리 누수/짓밟고 문제점 및 문서화'해야 할당된 메모리 요구할 수 있'OK'.

문제는 무엇입니까?만,당신이 통과 버퍼 realloc()및 realloc()반환합니다 당신은 새로운 포인터 영역을 사용해야 합니다-그리고 당신은 무시 반환하는 값입니다.따라서,realloc()는 아마도 해제된 원래의 메모리,그리고 당신은 그것을 통과 같은 포인터를 다시,그리고 불평하는 당신을 자유롭게 같은 메모리를 두기 때문에 당신이 통과 원래 값으로 그것을 다시합니다.이뿐만 아니라,메모리 누수,그러나 있다는 것을 의미를 계속 사용하는 원래의 공간와 요한이 다우의 어둠 속에서 포인트는 당신이 악용하 realloc(),지 얼마나 심각하게 하고 있다.도 있습 off-by-one 오류가하지 않기 때문에 당신은 할당을 위한 충분한 공간이 NUL'\0'는 종료 문자열입니다.

메모리 누수가 발생하기 때문에 당신을 제공하지 않습 메커니즘을 말해 호출자에 대한 마지막 값의 문자열입니다.기 때문에 당신은 유지 밟고 원래의 문자열 뒤에 공백을 그것은,그것은 다음과 같은 코드를 일했지만,이 경우 귀하의 전화 코드는 해방의 공간,그것도 얻을 것이 이중-무료러나 그것을 얻을 수 있습니다 핵심을 덤프 또는 이와 동등이기 때문에 메모리 제어 정보가 완전히 뒤섞여있다.

귀하의 코드도 없을 보호에 대한 무한한 성장 교체를 고려'Noel'와'Joyeux 노엘'.때마다,당신은 추가 7 자,하지만 당신은 다른 노엘에서 대체 텍스트 및 확장,그리고 등등.내 fixup(아래)하지 않는 이 문제를 해결-간단한 해결책은 아마 여부를 확인하는 문자열 검색에 나타나 교체 문자열대안을 건너 교체 문자열 검색을 계속합니다.두 번째는 일부 특수한 코딩 문제를 해결합니다.

그래서,제안된 개정하라는 기능입니다:

char *strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen - searchLen;
    char *find = input;

    while ((find = strstr(find, search)) != 0) {
        if (delta > 0) {
            input = realloc(input, strlen(input) + delta + 1);
            find = strstr(input, search);            
        }

        memmove(find + replaceLen, find + searchLen, strlen(input) + 1 - (find - input));
        memmove(find, replace, replaceLen);
    }

    return(input);
}

이 코드는 검색을 하지 않는 메모리 할당류와 충돌 아마(하지만 그렇지 않은 경우,메모리 누수)는 경우 realloc()은 실패합니다.볼티 Maguire 의'작성 고체 코드'이 책에 대한 광범위한 토론의 메모리 관리 문제입니다.

참고,편집하려고 하는 코드를 제거하의 html 코드를 탈출.

뿐만 아니라,비록 그것이었을 때부터 내가 사용하는 C/C++,realloc 성장하는 단 재사용의 메모리 포인터 값이 있는 경우 객실에는 메모리 후 원본다.

예를 들어,이것을 고려하십시오:

(xxxxxxxxxx..........)

하는 경우 포인터가 첫 번째 x,.의 메모리 위치,당신은 성장한 메모리 크기에 의해 지정된 변수에 의해 5 바이트를,그것을 성공합니다.이것은 물론 간단한 예제는 블록으로는 특정 크기 정렬하지만,어쨌든.

그러나,이후에 성장하고자 노력하고 그것은 또 다른 10 바이트를,그리고만 있는 5 가능한 것,이동해야한 블록 메모리에서 업데이트 포인터이다.

그러나,당신의 예를 전달하는 함수 포인터이 문자가 아닌 포인터 변수,그리고 따라서 동안 strrep 내부적으로 기능할 수 있을 조정할 변수를 사용하여,그것은 지역 변수를 strrep 기능과 당신의 통화 코드와 함께 남아있는 원래 포인터 변수의 값입니다.

이 포인터 값을,그러나이었다 해제됩니다.

귀하의 경우에는,입력의 원인입니다.

그러나 내가 다른 제안이 있습니다.귀하의 경우에는 것처럼 보인 입력 변수는 실제로 입력하는 경우,그것은 할 수 없이 수정된다.

나는 것입에 따라서도 다른 방법을 찾기 위해 무엇을 하고 싶지 않고,변경 입력, 으로,부작용을 다음과 같이 추적 어려울 수 있습니다.

이 작동하는 것 같다;

char *strrep(char *string, const char *search, const char *replace) {
    char *p = strstr(string, search);

    if (p) {
        int occurrence = p - string;
        int stringlength = strlen(string);
        int searchlength = strlen(search);
        int replacelength = strlen(replace);

        if (replacelength > searchlength) {
            string = (char *) realloc(string, strlen(string) 
                + replacelength - searchlength + 1);
        }

        if (replacelength != searchlength) {
            memmove(string + occurrence + replacelength, 
                        string + occurrence + searchlength, 
                        stringlength - occurrence - searchlength + 1);
        }

        strncpy(string + occurrence, replace, replacelength);
    }

    return string;
}

한숨이 어 게시 코드없이 그것은 빨?

realloc 은 이상한,복잡할 때만 사용해야 합니다 다루는 많은 메모리를 많이 번 두 번째입니다.즉-어디에서 실제로 그것은 코드를 더 빠르다.

본 코드

realloc(bytes, smallerSize);

사용되었고 일을 버퍼의 크기를 조정,그것을 만드는 작습니다.일 만에 대한 시대,그때 어떤 이유로 realloc 기로 결정하는 경우에도 단축 버퍼,그것은 당신에게 좋은 새로운 복사본입니다.그래서 당신은 충돌에서 임의의 장소 1/2 후 두 번째 나쁜 일이 일어났습니다.

항상 사용하의 반환 값 realloc.

나의 빠른다.

는 대신:
void strrep(char *input, char *search, char *replace)
try:
void strrep(char *&input, char *search, char *replace)

과에서 보다 신체:
input = realloc(input, strlen(input) + delta);

일반적으로 읽기에 대한 전달하는 기능을 인수 값으로/참조 및 realloc()description:).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top