문제

여기에 누군가가 지적한 최근 나에게 조각의 코드가 내 이용

char* name = malloc(256*sizeof(char));
// more code
free(name);

미국에서는 이 방법으로 설정하면 배열은 동일했을 사용하여

char name[256];

고는 두 가지 방법의 사용이 필요하 무료().내가 잘못된 경우도록할 수 있는 사람이 있었을 설명해 주시기 바랍에서 낮은 수준 조건의 차이가 무엇입니까?

도움이 되었습니까?

해결책

첫 번째 코드에서 메모리는 힙에 동적으로 할당됩니다. 해당 메모리는 Free ()로 해제되어야합니다. 수명은 임의적입니다. 기능 경계 등을 교차 할 수 있습니다.

두 번째 코드에서, 256 바이트는 스택에 할당되며 함수가 반환 될 때 (또는 모든 함수 외부에있는 경우 프로그램 종료시) 자동으로 재생됩니다. 따라서 무료로 전화 할 필요가 없습니다 (). 누출은 없지만 기능의 끝을 넘어서도 살지 않습니다.

메모리 요구 사항을 기반으로 두 가지 중에서 선택하십시오.

부록 (PAX) :

NED에 추가 할 수 있다면 대부분의 구현은 일반적으로 스택보다 더 많은 힙을 제공합니다 (적어도 기본적으로). 이미 스택이 부족하거나 심하게 재귀적인 작업을 수행하지 않는 한 일반적으로 256 바이트에 대해서는 중요하지 않습니다.

또한 (char) 크기는 항상 표준에 따라 1이므로 불필요한 곱을 곱할 필요가 없습니다. 컴파일러는 아마도 그것을 최적화 할 것이지만, 코드는 추악한 IMnsho를 만듭니다.

끝 부록 (PAX).

다른 팁

그리고 두 가지 방법은 free ()를 사용해야합니다.

아니요, 첫 번째는 무료 사용이 필요합니다. 두 번째는 스택에 할당됩니다. 그것은 할당하는 것이 엄청나게 빠릅니다. 이봐:

void doit() {
    /* ... */
    /* SP += 10 * sizeof(int) */
    int a[10];
    /* ... (using a) */

} /* SP -= 10 */

당신이 그것을 만들 때, 컴파일 타임의 컴파일러는 크기를 알고 스택에 올바른 크기를 할당합니다. 스택은 어딘가에 위치한 연속 메모리의 큰 덩어리입니다. 스택에 무언가를 넣으면 스택 포인터가 증가하거나 플랫폼에 따라 감소합니다. 범위를 벗어나면 반대가되고 배열이 해제됩니다. 자동으로 발생합니다. 따라서 그런 식으로 생성 된 변수는 가지고 있습니다 자동적 인 저장 시간.

Malloc 사용은 다릅니다. 임의의 큰 메모리 청크를 주문합니다 ( FREESTORE). 런타임은 합리적으로 큰 메모리 블록을 조회해야합니다. 크기는 런타임에 결정될 수 있으므로 컴파일러는 일반적으로 컴파일 시간에 최적화 할 수 없습니다. 포인터가 범위를 벗어나거나 복사 할 수 있으므로 메모리가 할당 된 메모리와 메모리 주소가 할당 된 포인터 사이에 고유 한 커플 링이 없으므로 오래 전에 기능을 떠난 경우에도 메모리가 여전히 할당됩니다. . 시간이 오면 Malloc에서 얻은 주소를 무료로 전달해야합니다.

C99라고하는 일부 "최근"C 형태는 배열을 런타임 크기로 제공 할 수 있습니다. 즉, 당신은 할 수 있습니다 :

void doit(int n) {
    int a[n]; // allocate n * sizeof(int) size on the stack */
}

그러나 사용할 이유가 없다면 그 기능을 피해야합니다. 한 가지 이유는 안전하지 않기 때문입니다. 더 이상 메모리를 사용할 수 없으면 어떤 일이 발생할 수 있습니다. 다른 하나는 C99가 컴파일러 중에서 매우 휴대가 아니라는 것입니다.

여기에는 세 번째 가능성이 있습니다. 즉, 배열은 함수 외부로 선언 될 수 있지만 정적으로는

// file foo.c
char name[256];

int foo() {
    // do something here.
}

나는 누군가가 이것이 C에서 부적절하다고 느꼈기 때문에 다른 질문에 대한 답변에 오히려 놀랐습니다. 여기에는 언급되지 않았으며, 나는 이것에 대해 약간 혼란스럽고 놀랐습니다 ( "요즘 학교에서 아이들을 가르치고 있는가?").

이 정의를 사용하는 경우 메모리는 힙이나 스택에가 아니라 이미지의 데이터 공간에 정적으로 할당됩니다. 따라서 Malloc/Free와 같이 관리되어서는 안되며 자동 정의와 마찬가지로 주소를 재사용하는 것에 대해 걱정하지 않아도됩니다.

여기서 "선언 된"vs "정의 된 전체를 기억하는 것이 유용합니다. 여기 예입니다

/* example.c */

char buf1[256] ;           /* declared extern, defined in data space */
static char buf2[256] ;    /* declared static, defined in data space */
char * buf3 ;              /* declared extern, defined one ptr in data space */
int example(int c) {       /* c declared here, defined on stack */
    char buf4[256] ;       /* declared here, defined on stack   */
    char * buf5 = malloc(256)]   /* pointer declared here, defined on stack */
                           /* and buf4 is address of 256 bytes alloc'd on heap */
    buf3 = malloc(256);    /* now buf3 contains address of 256 more bytes on heap */

    return 0;              /* stack unwound; buf4 and buf5 lost.      */
                           /* NOTICE buf4 memory on heap still allocated */
                           /* so this leaks 256 bytes of memory */
}

이제 완전히 다른 파일로

/* example2.c */

extern char buf1[];             /* gets the SAME chunk of memory as from example.c */
static char buf2[256];          /* DIFFERENT 256 char buffer than example.c */
extern char * buf3 ;            /* Same pointer as from example.c */
void undoes() {
     free(buf3);                /* this will work as long as example() called first */
     return ;
}

이것은 잘못된 것입니다 - 배열 선언은 무료가 필요하지 않습니다. 또한, 이것이 함수 내에 있으면 스택에 할당되며 (메모리가 제공되는 경우) 함수 반환으로 자동으로 릴리스됩니다. 발신자에 대한 참조를 전달하지 마십시오!

분 귀하의 문의

char* name = malloc(256*sizeof(char)); // one statement
char *name; // Step 1 declare pointer to character
name = malloc(256*sizeof(char)); // assign address to pointer of memory from heap
name[2]; // access 3rd item in array
*(name+2); // access 3rd item in array
name++; // move name to item 1

번역:이름은 이제에 대한 포인터 캐릭터에 할당된 주소의 일부 메모리에 힙

char name[256]; // declare an array on the stack
name++; // error name is a constant pointer
*(name+2); // access 3rd item in array
name[2]; // access 3rd item in array
char *p = name;
p[2]; // access 3rd item in array
*(p+2); // access 3rd item in array
p++; // move p to item 1
p[0]; // item 1 in array

번역:이름은 일정한 포인터인 문자는 어떤 스택 메모리

에서는 C 배터 같은 일이 더 많거나 적습니다.배열은 상수 포인터를 하는 지 확인해 주시기 바랍니다.주요할 때 call malloc 당신이 당신의 메모리 힙 모든 메모리에서 촬영한 힙에서 해방되어야 힙.를 선언할 때는 배열의 크기 할당된 메모리에서 스택입니다.할 수 없습니다 무료로 이 메모리기 때문에 무료 무료로 메모리에서 힙.메모리에 스택이 자동으로 해제할 때에 현재 프로그램 단위의 반환합니다.두 번째 예에서 무료(p)오류가 될 것이 또한 있다.p 포인터 이름 배열에 스택입니다.그래서 해방하여 p 을 시도하고 있는 메모리에 스택입니다.

이것은 다르지 않:

int n = 10;
int *p = &n;

을 확보 p 이 경우에 오류가 될 것이기 때문에 p 포 n 는 변수에 스택입니다.따라서 p 을 보유하고 메모리 위치에서 스택을 해제할 수 없습니다.

int *p = (int *) malloc(sizeof(int));
*p = 10;
free(p);

이 경우 무료이기 때문에 정확 p 포인트 메모리 위치에 힙는 할당해 malloc.

이 실행중인 위치에 따라 스택 공간이 큰 프리미엄 일 수 있습니다. 예를 들어 Verizon/Alltel 핸드셋 용 Brew 코드를 작성하는 경우 일반적으로 소형 스택으로 제한되지만 힙 액세스가 증가하고 있습니다.

또한, char []는 문자열에 가장 많이 사용되므로 문자열 구성 방법이 항상 256 명 (또는 어떤 숫자로든 당신의 숫자가 무엇이든 희망하는 것이 아니라 문제의 문자열에 필요한 메모리를 할당하는 것은 나쁜 생각이 아닙니다. 법령) 충분합니다.

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