3

私が行った簡単なコーディング手順と、問題に直面している領域について説明します

main.cpp

int main()
{
    int cnt_map,i=1,value;

   /* My question is about this char pointer "key" */ 
    char *key =(char*)malloc(sizeof(char) * 25);

   if(key!=NULL)
   {
     printf("Key value is not NULL,its value is:%x\n",key) ;
     cout<< "Enter the number of elements required in container map"<<endl;
     cin >> cnt_map;
     for (i=1;i<=cnt_map;i++)
     {
       cout << "Enter the key : ";
       cin >>key;
       cout << "Enter the key value:" ;
       cin >>value;
       printf("value pointed by ptr key: %s, value in ptr: %x\n", key,key);
       c -> add_map1(key,value); //Function inserts value to map container
       key+=sizeof(key);
     }
     c -> size_map1();           //Function displays size of map container
     c -> display_map1();        //Function displays contents of map container
  if(key)
  {
    printf("FINALLY:value pointed by ptr key: %s, value in ptr: %x,size:%d\n",key, key, sizeof(key));
    free(key);
  } 
 }
return 0;
}

上記のコードをコンパイルして実行しようとすると、コードを正常にコンパイルできましたが、アプリケーションを実行しようとすると「glibc が検出されました: ダブル フリーまたは破損」が発生しました。

私の質問は、char pointer( char *key =(char*)malloc(sizeof(char) * 25);) を作成し、malloc を使用してメモリを正常に割り当てたことです。そのcharポインターを解放しようとしたときにプロセスを完了した後、二重解放または破損エラーが発生します。malloc/calloc を使用してメモリに割り当てられた変数は、最終的に解放する必要があることを学びました。このエラーが発生する理由を教えてください。なぜこれを行うべきではないのですか? メモリ操作がどのように進行しているか教えてくださいchar* key(できれば絵で)。

注: 上記のコードは完全なコードではありません。問題が発生している場所を説明しただけで、ポインター変数を解放していない場合、アプリケーションは正常に実行されています。

4

4 に答える 4

7

これを行うことにより:

key+=sizeof(key);

変数は、key割り当てたメモリの先頭を指していません。元のポインタを に渡す必要がありますfree()。最後に正しくできるように、元のポインターを別の変数に格納する必要がありますfree()

(その行を単純に削除できるかもしれません - 4 または 8 のいずれかであることを考えると、それが何をしているのかわかりませんsizeof(key)。冗長であると思われます。)

于 2013-06-27T13:00:13.363 に答える
5

それは、次の行が原因です: key+=sizeof(key);. key返されたアドレスと同じアドレスが含まれていませんmalloc

例えば:

char *key =(char*)malloc(sizeof(char) * 25);

malloc がアドレスを返すとしましょう20000(完全にばかげたアドレスです。これは単なる例です)。

を実行しているので、key = 20000 + 4 = 20004 です。問題は、20000 ではなくアドレス 20004 を指しているkey+=sizeof(key);を解放しようとしていることです。key

それを修正するには、これを試してください:

int main()
{
    int cnt_map,i=1,value;
    char *key_save;

   /* My question is about this char pointer "key" */ 
    char *key =(char*)malloc(sizeof(char) * 25);

    key_save = key;
   if(key!=NULL)
   {
     printf("Key value is not NULL,its value is:%x\n",key) ;
     cout<< "Enter the number of elements required in container map"<<endl;
     cin >> cnt_map;
     for (i=1;i<=cnt_map;i++)
     {
       cout << "Enter the key : ";
       cin >>key;
       cout << "Enter the key value:" ;
       cin >>value;
       printf("value pointed by ptr key: %s, value in ptr: %x\n", key,key);
       c -> add_map1(key,value); //Function inserts value to map container
       key+=sizeof(key);
     }
     c -> size_map1();           //Function displays size of map container
     c -> display_map1();        //Function displays contents of map container
  if(key)
  {
    printf("FINALLY:value pointed by ptr key: %s, value in ptr: %x,size:%d\n",key, key, sizeof(key));
    free(key_save);
  } 
 }
return 0;
}
于 2013-06-27T13:01:02.850 に答える
1

次の行を削除するだけです。

key+=sizeof(key);

key文字列の配列へのポインタではなく、単一の文字列へのポインタです。これをインクリメントするたびに、文字列内の使用可能なスペースが減少します。初めてキーを読み取るときは、25 バイトが使用可能です。次回はkey4 バイトまたは 8 バイト増加しましたが、割り当てられたスペースの末尾は変更されていないため、使用できるのは 21 バイトまたは 17 バイトのみです。3 回目はわずか 17 または 9 バイトなどです。数回繰り返した後、key割り当てたメモリ ブロックの末尾を超えてインクリメントし、未割り当てメモリ (または他のデータ構造に割り当てられているメモリ) への書き込みを開始します。これは未定義の動作であり、プログラムで予期しないエラーが発生する可能性が高くなります。

C++ を使用しているため、文字列のstd::string代わりに、通常の配列の代わりに使用する必要があります。これらのデータ構造は必要に応じて自動的に拡張されるため、このようなバッファ オーバーフローを回避できます。char[]std::vector

于 2013-06-27T13:22:29.403 に答える
-1

これはあなたのコードを考慮していませんが、リーダーライターの問題(オペレーティングシステム) http://en.wikipedia.org/wiki/Readers%E2%80%93writers_problemで同じ問題がありました。

これは、ファイル ポインターがグローバルであるため、いずれかのリーダーが読み取りを試みたときに、別の読み取りがファイル ポインターを読み取って閉じたため、読み取りが完了していない別のリーダーが読み取り後にファイル ポインターを閉じようとしたときに発生しました。そのため、ファイル ポインターは既に閉じられており、ファイルを指していませんでした。私が使用したソリューション。ファイルポインターをグローバルに宣言する代わりに、リーダー関数に対してローカルに宣言し、それ以外の場合はNULLのファイルポインターをチェックし、NULLの場合はファイルポインターを閉じません。

#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
sem_t x,wsem;
int rc=0;
char ch;
char str[20];
void *reader(void *);
void *writer(void *);


int main()
{
 int nw,nr,i=0,j=0;
 pthread_t w[10],r[10];
 sem_init(&x,0,1);
 sem_init(&wsem,0,1);
 rc=0;
 printf("Enter the no of readers:");
 scanf("%d",&nr);
 printf("Enter the no of writers");
 scanf("%d",&nw);
 while(i<nw || j<nr) 
 {

  if(i<nw)
  {
pthread_create(&w[i],NULL,writer,(void *)i);

i++;
  }
  if(j<nr)
  {
pthread_create(&r[j],NULL,reader,(void *)j);

    j++;
  }
 }
 for(i=0;i<nw;i++)
 {
pthread_join(w[i],NULL); 
 }
 for(j=0;j<nr;j++)
 {
pthread_join(r[j],NULL);
 }

 return 0;
}

void *reader(void *arg)
{
 FILE *fptr;
 sem_wait(&x);
 rc++;
 if(rc==1)
  sem_wait(&wsem);
 sem_post(&x);

 printf("\nreader %d:",arg);
 fptr=fopen("temp.txt","r+");
 while(fgets(str,10,fptr)!=NULL)
 {
  printf("%s",str);
 }
 printf("\n");
 fclose(fptr);
 sem_wait(&x);
 rc--;
 if(rc==0)
    sem_post(&wsem);
 sem_post(&x);
}


void *writer(void *arg)
{
 FILE *fptr1;
 sem_wait(&wsem);  
 printf("\nwriter-%d:\n",arg);
 fptr1=fopen("temp.txt","a+");
 printf("enter the string:");
 scanf("%s",str);
 fputs(str,fptr1);
 fclose(fptr1);  
 sem_post(&wsem);
}
于 2014-04-12T12:37:24.270 に答える