2017-06-23 18 views
-2

私は私がこのようにしようとしたtime.soに1ブロックずつ増やしてSTACKのdynamicallを作成する必要がスタックのrealloc():reallocの無効次のサイズとのmalloc():高速なmallocのメモリ破損

typedef struct cool { 
    int value; 
}arr; 

typedef struct stack { 
    int top; 
    arr **st; 
}STACK; 

を作成しています..私は()私はこのようなエラーが発生します作成呼び出すことによってreallocteなしproblem..but再び私が作ると呼ばれる最初の時間()のための

int size = 1; 
STACK *mainstack; 

mainstack = (STACK *) malloc (sizeof(STACK)); 
create(mainstack); 
create(mainstack); 
create(mainstack); 

void create(STACK *mainstack) { 
     if((mainstack = realloc(mainstack, (size + 1))) != NULL) { 
       mainstack[size].st = (arr **) malloc(10 * sizeof(arr*)); 
     } 
     ++size; 
} 

... のrealloc():無効次のサイズ... ..

ので、私はこのようなエラーが...

のmalloc()を取得後、再度

mainstack = realloc(mainstack, (size + 1) * sizeof(STACK)); 

でのreallocを変更:私はその作業を作成すると呼ばれるgood.but aftrerメモリ破損の高速

2回エラーを示す第三の呼び出し。 誰かが実際にそれらの背後に何を教えてください?またはこれらのエラーを取得せずに自分の考えを満たすために他の方法があります。..

+3

'create'の' mainstack'は、呼び出し側関数の 'mainstack'のコピーです。値を変更しても元の値は変更されません。 – mch

+0

そして 'STACK'の定義が与えられると、そのサイズは固定されます。 'realloc'(そして、' malloc() ')は、' STACK'のメンバ 'st'です。 –

+0

そして、この「サイズ」は何を表していますか?スタックエントリの数?そして、 'はsizeof(* mainstack)'ここで失礼なことしようとしていない割り当て – tilz0R

答えて

1

これは動作しないことができます。

void create(STACK *mainstack){ 
    if ((mainstack = realloc(mainstack, (size + 1))) != NULL) { 
    mainstack[size].st = (arr **)malloc(10 * sizeof(arr*)); 
    } 
    ++size; 
} 

mainstack = realloc(mainstack...はの終わりでスコープの外に行くローカル変数mainstackを修正関数。

したがって、create(mainstack);の後には、mainstackは変更されません。グローバル変数sizeを使用して、全体的なデザインは非常に良いではありませんし、createのエラー処理がbogousである、と述べた

STACK *create(STACK *mainstack){ 
    if ((mainstack = realloc(mainstack, (size + 1))) != NULL) { 
    mainstack[size].st = (arr **)malloc(10 * sizeof(arr*)); 
    } 
    ++size; 

    return mainstack; 
} 

int main() 
{ 
    int size = 1; 
    STACK *mainstack; 

    mainstack = malloc(sizeof(STACK)); 
    mainstack = create(mainstack); 
    mainstack = create(mainstack); 
    mainstack = create(mainstack); 
} 

簡単な例:

void foo(int bar) 
{ 
    bar = 2; 
} 
... 

int x = 123; 
foo(x); 
// x contains 123 and n ot 2 

あなたは、たとえば、これを必要とします。

1

したがって、動的に成長するスタックを作成したいのですが、コードでどこが間違っていたのかを説明した回答があります。これについて

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

typedef struct Stack 
{ 
    size_t capacity; // how many items the stack can hold right now 
    size_t index;  // index of the first unused element 
         // (kind of a "stack pointer") 
    int stack[];  // the elements, variable length 
} Stack; 

Stack *Stack_create(size_t n) 
{ 
    // create stack with room for `n` elements 
    Stack *self = malloc(sizeof(Stack) + n * sizeof(int)); 
    // you need to add `n * sizeof(int)` here for the flexible array member 

    if (!self) exit(1); 
    self->capacity = n; 
    self->index = 0; 
    return self; 
} 

void Stack_destroy(Stack *self) 
{ 
    if (!self) return; 
    free(self); 
} 

void Stack_push(Stack **self, int val) 
{ 
    Stack *s = *self; 
    if (s->index == s->capacity) 
    { 
     // if necessary, double the number of elements the stack can hold 
     s->capacity *= 2; 
     s = realloc(s, sizeof(Stack) + s->capacity * sizeof(int)); 
     if (!s) exit(1); 
     *self = s; 
    } 
    s->stack[s->index++] = val; 
} 

int Stack_pop(Stack *self, int *val) 
{ 
    if (self->index) 
    { 
     *val = self->stack[--self->index]; 
     return 1; 
    } 
    else 
    { 
     return 0; 
    } 
} 

int main(void) 
{ 
    Stack *stack = Stack_create(5); 

    Stack_push(&stack, 47); 
    Stack_push(&stack, 12); 
    Stack_push(&stack, 73); 
    Stack_push(&stack, 5); 
    Stack_push(&stack, 13); 
    Stack_push(&stack, 23); 

    int val; 
    while (Stack_pop(stack, &val)) 
    { 
     printf("%d ", val); 
    } 
    putchar('\n'); 

    Stack_destroy(stack); 

    return 0; 
} 

注:

    それでもデザインは、したがって、私はあなたに私が まっすぐ進む、単一の structを使用して検討したいソリューションのいくつかのコメントのコードを紹介し、少し複雑に思えます
  • ここでは、簡略化のため、malloc()realloc()のエラーチェックは最小限です。実際には多くのことはできませんが、おそらくexit(1)で十分ですが、プログラムが複雑な場合は、代わりにエラーを呼び出し元に返すことができます。 fflush()ファイルなど

  • 通常はたくさんrealloc()の呼び出しを(彼らは高価なことができます)避けたいです。事前にスペースを割り振り、必要があればスペースを2倍にすることは、そのようなデータ構造の共通のアプローチです。

  • あなたはStack_push()へのダブルポインタを渡すために持っ気に入らない場合、あなたは確かに代わり、このような柔軟な配列メンバーのポインタを使用する必要があります。

    typedef struct Stack 
    { 
        size_t capacity; 
        size_t index; 
        int *stack; 
    } Stack; 
    

    が、あなたは、このためのスペースを割り当てる必要がmalloc()に別のコールでのみ、このメンバーであなたのreallocを必要としています。

関連する問題