1

malloc()次のような部分文字列を返すが、プロセスで使用せずに、コード内の他の場所で関数を使用して関連するメモリを解放することを心配する必要がない部分文字列関数を実装するにはどうすればよいですかfree()。これも可能ですか?

const char *substring(const char *string, int position, int length)
{
    char *pointer;
    int c;

    pointer = malloc(length+1);

    if (pointer == NULL)
    {
        printf("Unable to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    for (c = 0 ; c < position -1 ; c++)
        string++;

    for (c = 0 ; c < length ; c++)
    {
        *(pointer+c) = *string;
        string++;
    }

    *(pointer+c) = '\0';

    return substr;
}

更新:2012年12月30日

すべての回答とコメントを検討した結果、基本的に私がやろうとしているのは動的なサイズの配列(つまりサブストリング)を作成することであり、Cでは何らかのmalloc()関数とその後free()のサブストリングポインタの呼び出し、またはガベージコレクタの助けなし。libgc@elhadiから親切に提案されたように、ガベージコレクターを統合しようとしましたが、これまでのところ、Xcodeプロジェクトでこれを機能させることができませんでしたmalloc()だから私はとで次のコードを使用することに固執することを選択しましたfree()

char * subStr(const char* srcString, const int offset, const int len)
{
    char * sub = (char*)malloc(len+1);
    memcpy(sub, srcString + offset, len);
    sub[len] = 0;
    return sub;
}

int main()
{    
    const char * message = "hello universe";
    char * sub = subStr( message, 6, 8 );
    printf( "substring: [%s]", sub );
    free(sub);
}
4

5 に答える 5

6

2つのオプションがあります。

ソース文字列を破棄できる場合(通常は悪いことです):

{
    string[ position + length] = 0;
    return & string[ position ];
}

注:(ColeJohnsonsの注を参照してください:freeは返されたポインターでは機能しなくなりました!)

ソース文字列を変更できない場合:呼び出し元が心配する必要があるように、メソッドのシグネチャを変更します。

const char *substring(const char *source, char* destination, int position, int length)

そして、変更された文字列を宛先に配置します(そしてそれを返します)。

そして、これについても考えないでください:

const char *substring(const char *string, int position, int length)
{
    char *pointer;
    int c;
    static char modifiedString[256];
 ...
    return modifiedString;
}

変更された結果のために関数内で静的変数を使用する...(これはスレッドセーフではありません(再入可能ではありません!))

于 2012-12-28T08:03:46.180 に答える
2
const char *substring(const char *string, char *substr, int position, int length)
{
    int c;

    for (c = 0 ; c < position -1 ; c++)
        string++;

    for (c = 0 ; c < length ; c++)
    {
        *(substr+c) = *string;
        string++;
    }

    *(substr+c) = '\0';

    return substr;
}

呼び出し関数...

int main(int argc, char * argv[]) {
    char substr[10];

    substring("hello! World", &substr[0], 2, 4);
}
于 2012-12-28T08:08:56.293 に答える
2

ローカル バッファ (自動配列) と次のような関数を使用します。

void substr(char *dst, const char *src, size_t loc, size_t len)
{
    memcpy(dst, src + loc, len);
    dst[len] = 0;
}

次のように呼び出します。

const size_t size = 3;
char buf[size + 1]; // this is an auto array, it will be "freed" at the end of the scope
substr(buf, "abcdFOObar", 4, size);

len + 1バッファー オーバーフロー エラーを回避するために、バッファーが少なくともバイト長であることを常に確認してください。

于 2012-12-28T08:10:56.237 に答える
1

それを行う最良の方法は次のとおりです。

typedef struct vstr_t {
     char *s;
     int   len;
} vstr_t;

#define vstr_set(d, l)                  \
    ({                                  \
        vstr_t vs = {.s = d, .len = l}; \
                                        \
        vs;                             \
    })

#define vstr_fmt_arg(vs) (vs).len, (vs).s

int main()
{    
    const char *message = "hello universe";

    printf( "substring: [%.*s]\n", vstr_fmt_arg(vstr_set(smpl + 6, 8)));

    return 0;
}
于 2012-12-28T08:49:21.140 に答える
0

ガベージ コレクタを使用できます。最初にメモリを割り当てると、不要になったときにガベージ コレクタがメモリを解放します。
あなたが含める必要があります

#include "gc.h"

主に、次のようなものを作成する必要があります

GC_INIT();  /* Optional on Linux/X86;*/

あなたの substr 関数は次のとおりです。

char *substr(const char* buffer, const int offset, int len)
{
    char sub = (char*)GC_MALLOC(len+1);
    memcpy(sub, buffer + offset, len);
    sub[len] = 0;
    return sub;
}

リンクする必要がありますlibgc.a

于 2012-12-28T09:47:01.967 に答える