1

私はこれを正しく行っていると信じていますが、確認したかったのです。プログラムでは、関数によって返される割り当てられたメモリを指す 2 つのポインターを使用しています。そのメモリを使い終わったらfree()、それを使いますが、同じポインターを使用して、新しく割り当てられたメモリ空間を指します。これが私の意味の例を示す私のプログラムです(私の思考プロセスを示すためにコメントされています):

int main(void)
{
    char *data, *url;
        int i = 1;

    while(i)
    {
        printf("Enter URL: ");
        if(!(url = getstr())) return 1;                                  //url now points to allocated memory from getstr();
        if(strlen(url) <= 0) i = 0;
        if(data = readsocket(url, 80, "http")) printf("\n%s\n\n", data); //data now points to allocated memory from readsocket();
        else printf("\n\n");
        free(url);                                                       //free allocated memory that url points to url
        free(data);                                                      //free allocated memory that data points to data
    }
    return 0;
}

これは正しいですか、それともこれを行うためのより一般的に好ましい方法はありますか? それとも、私はそれを完全に間違っていますか?

4

4 に答える 4

5

getstr関数とreadsocketメモリを内部的に malloc すると仮定すると、これは完全に問題ありません。

私の唯一の提案は、メモリを解放するのと同じスコープでメモリを割り当てることが役立つことが多いということです。これは、いつ解放する必要があるかを判断するのに役立ちます。

例えば:

url = malloc(URL_MAX_LEN);
if (!url) return 1;
if (!getstr(url)) {
    free(url);
    return 1;
}
/* do something with url */
free(url);

多くのオブジェクトと終了ポイントがある場合は、goto を使用してこれを行うと便利です。

object1 = malloc(OBJECT1_SIZE);
/* do work, if there's an error goto exit1 */
object2 = malloc(OBJECT2_SIZE);
/* do work, if there's an error goto exit2 */
object3 = malloc(OBJECT3_SIZE);
/* do work, if there's an error goto exit3 */
exit3:
free(object3);
exit2:
free(object2);
exit1:
free(object1);
return 1;

オブジェクトがより複雑になり、作成と破棄に多くの作業が必要になる場合は、malloc と free をラップできますが、リークを避けるために malloc/free とまったく同じ規則を create/destroy 関数に適用することが重要です。適切な方法として、作成に一致するように常に破棄する必要があります。そのように間違って行くのははるかに難しいです。

struct x *create_x() {
    struct x *p = malloc(10);
    p->val1 = 7;
    return p;
}
void destroy_x(struct x *p) {
    free(p);
}
于 2012-08-28T13:36:31.123 に答える
2

関数が関数getstrreadsocket使用してメモリを割り当てる場合、たとえばmalloc、あなたがしていることは問題ありません。

于 2012-08-28T13:36:14.483 に答える
2

コードに問題はありませんが、data と url にメモリを事前に割り当てて、これらを引数としてgetstrおよびreadsocket関数に渡すことができます。これはより効率的になります。

于 2012-08-28T13:35:59.383 に答える
1

ここに私が気づいたいくつかのことがあります:

  1. を使用iしてループを制御していますが、 を設定するi = 0と、プログラムは中かっこを閉じるまでずっと行かなければなりません。while (1)andbreakステートメントを使用して、i変数を削除することをお勧めします。

    while(1) {
        ...
        if (strlen(url) <= 0)
            break;
        ...
    }
    
  2. あなたが使用しif (data = readsocket(url, 80, "http"))ているのは技術的に間違っていませんが、誰かが比較のために間違える可能性があるため、少し誤解を招く可能性がありif (data == readsocket(url, 80, "http")ます。これはほぼ C プログラミングの「パターン」であり、if (!url = getstr()))オンラインで行ったのと同じように記述することをお勧めします。

    if ((data = readsocket(url, 80, "http")) != NULL) ...
    

    また

    if (!(data = readsocket(url, 80, "http"))) ...
    
  3. これはより「スタイル」関連ですが、別々の行に別々のステートメントを書く方が良いので、書かないでください

    if (!(url = getstr())) return 1
    

    むしろ

    if (!(url = getstr()))
        return 1;
    
  4. メモリの解放に関しては、うまくやっています

于 2012-08-28T13:49:51.630 に答える