편집 기록

편집 기록
  • 프로필 nowp님의 편집
    날짜2020.01.17

    문자열 포인터 질문


    두 코드의 차이점이 궁금합니다.

    1.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    void hstrrev(char* str);
    
    int main() {
    
        char str[100] = "program을 실행하기 전에 compile를 해야 한다.";
    
        puts(str);
    
        hstrrev(str);
    
        puts(str);
    
        return 0;
    }
    
    void hstrrev(char* str) {
    
        char* pstr;
        char* s = str;
    
        pstr = (char*)malloc(strlen(str) + 1);
        pstr = pstr + strlen(str);
    
        *pstr = NULL;
        pstr--;
    
        while (*s) {
            if (*s & 0x80) {
                *pstr-- = s[1];
                *pstr-- = s[0];
                s += 2;
            }
            else {
                *pstr-- = *s++;
            }
        }
        strcpy(str, pstr);
        free(pstr);
    }
    

    2.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    void hstrrev(char* str);
    
    int main() {
    
        char str[100] = "program을 실행하기 전에 compile를 해야 한다.";
    
        puts(str);
    
        hstrrev(str);
    
        puts(str);
    
        return 0;
    }
    
    void hstrrev(char* str) {
    
        char* pstr, * p;
        char* s = str;
    
        pstr = (char*)malloc(strlen(str) + 1);
        p = pstr + strlen(s);
    
        *p-- = NULL;
    
        while (*s) {
            if (*s & 0x80) {
                *p-- = s[1];
                *p-- = s[0];
                s += 2;
            }
            else {
                *p-- = *s++;
            }
        }
    
        strcpy(str, pstr);
        free(pstr);
    }
    

    문자열을 한글영어 구분 없이 거꾸로 출력하는 함수 hstrrev에서

    1.번 코드에서 함수 hstrrev에서 pstr을 str과 크기가 같게 동적 할당을 하게 한 후 pstr=pstr+strlen(str)을 하게 되면 현재 pstr은 메모리상에서 크기가 4인 포인터 변수가 생성 되고(포인터 변수는 항상 크기 4이기때문에) pstr이 이름없는 메모리(크기가str과 같은)의 시작번질를 가리키게 되는데

    이미지

    그럼 pstr=pstr+strlen(str)이라고 하면 pstr은 pstr이 가리키는 이름없는 메모리의 끝을 가리 키게 되지 안나요?(이게 질문입니다)

    이미지

    그후엔 그냥 아래 코드대로 실행 되게 되면 문자열이 거꾸로 출력이 될거라고 예상됬는데 이상한 오류가 뜨더라구요...

    오류 내용

    Debug Assertion Failed!
    
    Expression:_CrtlsValidHeapPointer(block)
    
    for information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
    
    (Press Retry to debug the application)
    

    그럼 이제 2.번 코드에선 위처럼 pstr을 동적 할당 하고나서 다른 포인터 변수하나를 만들어서(p) p=pstr+strlen(str) 라고하게 되면 마찬가지로, 동적 할당한 후 str길이와 같은 이름없는 메모리를 pstr이 가리키게 되는데 p=pstr+strlen(str) 이 식에 의해서 포인터 변수 p는 pstr이 가리키는 메모리의 끝을 가리키게 되고 결국 pstr=pstr+strlen(str)과 다를게 없다고 생각 하였습니다.

    이미지

    하지만 1.번코드는 오류가 생기고 2.코드는 잘 실행이 되더라구요...

    두코드에서 차이점은 포인터 변수 p를 만들어서 pstr이 가리키는 메모리의 끝을 읽냐 아니면 바로pstr에 pstr이 가리키는 메모리의 끝을 읽냐 인 것 같은데 즉,

    p=pstr+strlen(str)
    pstr=pstr+strlen(str)
    

    이 두 식의 차이를 모르겠습니다.

    아직 모르는게 너무도 많고 필력도 안좋아서 항상 수준낮은 질문만 하는 것 같은데 항상 답변 해주시는 분들께 진심으로 감사드립니다!

  • 프로필 알 수 없는 사용자님의 편집
    날짜2020.01.17

    문자열 포인터 질문


    두 코드의 차이점이 궁금합니다.

    1. '''#include

    include

    include

    void hstrrev(char* str);

    int main() {

    char str[100] = "program을 실행하기 전에 compile를 해야 한다.";
    
    puts(str);
    
    hstrrev(str);
    
    puts(str);
    
    return 0;
    

    }

    void hstrrev(char* str) {

    char* pstr;
    char* s = str;
    
    pstr = (char*)malloc(strlen(str) + 1);
    pstr = pstr + strlen(str);
    
    *pstr = NULL;
    pstr--;
    
    while (*s) {
        if (*s & 0x80) {
            *pstr-- = s[1];
            *pstr-- = s[0];
            s += 2;
        }
        else {
            *pstr-- = *s++;
        }
    }
    strcpy(str, pstr);
    free(pstr);
    

    }'''

    2.

    include

    include

    include

    void hstrrev(char* str);

    int main() {

    char str[100] = "program을 실행하기 전에 compile를 해야 한다.";
    
    puts(str);
    
    hstrrev(str);
    
    puts(str);
    
    return 0;
    

    }

    void hstrrev(char* str) {

    char* pstr, * p;
    char* s = str;
    
    pstr = (char*)malloc(strlen(str) + 1);
    p = pstr + strlen(s);
    
    *p-- = NULL;
    
    while (*s) {
        if (*s & 0x80) {
            *p-- = s[1];
            *p-- = s[0];
            s += 2;
        }
        else {
            *p-- = *s++;
        }
    }
    
    strcpy(str, pstr);
    free(pstr);
    

    }'''

    문자열을 한글영어 구분 없이 거꾸로 출력하는 함수 hstrrev에서

    1.번 코드에서 함수 hstrrev에서 pstr을 str과 크기가 같게 동적 할당을 하게 한 후 pstr=pstr+strlen(str)을 하게 되면 현재 pstr은 메모리상에서 크기가 4인 포인터 변수가 생성 되고(포인터 변수는 항상 크기 4이기때문에) pstr이 이름없는 메모리(크기가str과 같은)의 시작번질를 가리키게 되는데

    이미지

    그럼 pstr=pstr+strlen(str)이라고 하면 pstr은 pstr이 가리키는 이름없는 메모리의 끝을 가리 키게 되지 안나요??(이게 질문입니다)

    이미지

    그후엔 그냥 아래 코드대로 실행 되게 되면 문자열이 거꾸로 출력이 될거라고 예상됬는데 이상한 오류가 뜨더라구요...

    오류 내용

    Debug Assertion Failed!

    Expression:_CrtlsValidHeapPointer(block)

    for information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

    (Press Retry to debug the application)

    그럼 이제 2.번 코드에선 위처럼 pstr을 동적 할당 하고나서 다른 포인터 변수하나를 만들어서(p) p=pstr+strlen(str) 라고하게 되면 마찬가지로, 동적 할당한 후 str길이와 같은 이름없는 메모리를 pstr이 가리키게 되는데 p=pstr+strlen(str) 이 식에 의해서 포인터 변수 p는 pstr이 가리키는 메모리의 끝을 가리키게 되고 결국 pstr=pstr+strlen(str)과 다를게 없다고 생각 하였습니다.

    이미지

    하지만 1.번코드는 오류가 생기고 2.코드는 잘 실행이 되더라구요...

    두코드에서 차이점은 포인터 변수 p를 만들어서 pstr이 가리키는 메모리의 끝을 읽냐 아니면 바로pstr에 pstr이 가리키는 메모리의 끝을 읽냐 인 것 같은데 즉,

    p=pstr+strlen(str) pstr=pstr+strlen(str)

    이 두 식의 차이를 모르겠습니다ㅠㅠ

    아직 모르는게 너무도 많고 필력도 안좋아서 항상 수준낮은 질문만 하는 것 같은데 항상 답변 해주시는 분들께 진심으로 감사드립니다!