1

プログラムのコードは次のとおりです。

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

char * cloning(char * q){
    char s[strlen(q)];
    int i;
    for(i = 0; i < strlen(q); i++)
        s[i] = q[i];
    return s;
}

int main(){
    char q[] = "hello";
    char *s = cloning(q);
    return 0;
}

コンパイル後に警告が表示されるので、戻り値を次のように変更しました。

char *b = s;
return b;

このようにして、警告を解決できます。ただし、関数 cloning() 内では、sizeof(s) は 5 ですが、strlen(s) は 7 であることがわかりました。また、char s[strlen(q)] を単純に char s[5] に変更しても、出力は引き続き正しくない。誰でもこの問題を説明できますか? どうもありがとうございました。

4

6 に答える 6

6

char s[strlen(q)]はローカル変数であるため、そのアドレスを返すと、未定義の動作が発生します。したがって、配列を使用するstrdup()malloc()動的に割り当てることができるため、関数から戻ったときに配列 s がヒープ上で確実に利用できるようになります。返された配列も同様に編集する必要がありfree()ます。そうしないと、メモリリークが発生します:)

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

char * cloning(char * q){
    char *s = malloc(strlen(q)+1);
    // if you write char s[strlen(q)], it is defined locally, and thus on return gives an undefined behaviour
    int i;
    for(i = 0; i < strlen(q)+1; i++)
        s[i] = q[i];
    return s;
}

int main(){
    char q[] = "hello";
    char *s = cloning(q);
    free(s);
    return 0;
}
于 2013-05-27T05:18:18.333 に答える
3
char s[strlen(q)];

可変長配列です。malloc されたバッファと同様に、そのサイズは実行時に決定されます。malloc されたバッファとは異なり、関数が戻ると存在しなくなります。

于 2013-05-27T05:22:29.863 に答える
2

C標準のバージョンに関係なく、標準Cでこれを行う適切な方法は次のとおりです。

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

char* cloning (const char* str)
{
  char*  clone;
  size_t size = strlen(str) + 1;

  clone = malloc(size);
  if(clone == NULL)
  {
    return NULL;
  }

  memcpy(clone, str, size); 

  return clone;
}

int main(){
    char original[] = "hello";
    char* clone = cloning(original);

    if(clone == NULL)
    {
      puts("Heap allocation failed.");
      return 0;
    }

    puts(clone);

    free(clone);
    return 0;
}
于 2013-05-27T06:26:05.257 に答える
0

C の動的配列は、Malloc と Calloc を使用して宣言されます。ググってみてください。

例えば:

 char *test;

    test = (char *)malloc(sizeof(char)*Multiply_By);
于 2013-05-27T05:17:07.203 に答える