Понимание двойных пустых указателей в C - PullRequest
0 голосов
/ 22 сентября 2019

Я пытаюсь привести очень простые примеры, чтобы понять, как работают пустые указатели.Вот пример, который я написал для получения строки void* и приведения ее к «рабочему» типу и печати некоторых ее аспектов:

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

    // Create a void pointer which "acts like" a string
    void * string = "hello";

    // "Cast" the string so it's easier to work with
    char * string_cast = (char*) string;

    // Print the string and a character in it
    printf("The string is: %s\n", string_cast);
    printf("The third character is: %c\n", string_cast[2]);

    // How to now do something like:
    // (1) void pointer_to_string_obj = ?
    // (2) cast that pointer_to_string_obj to a normal string
    // (3) print the string like it would normally be done


}

Может кто-нибудь показать пример ручного создания строкиуказатель типа *(char**) и почему этот тип должен быть создан в первую очередь (почему не просто обычный char*?).Я прошу прощения, если мой вопрос является широким, но в основном я пытаюсь выяснить различные типы пустых указателей и где я сейчас нахожусь в моем самом начинающем понимании, это немного сбивает с толку, и поэтому несколько примеров было бы очень полезно.

1 Ответ

1 голос
/ 22 сентября 2019

Итак, я придумал хороший пример двойного указателя на пустоту (то есть void**).Один из способов сократить количество ошибок, не связанных с двойной ошибкой, - это всегда устанавливать указатели в NULL после их освобождения.

Мы можем сделать это так (сомнительный стиль):

myprojectinclude.h:

/* must happen after any standard headers */
void freep(void **pointer);
#define free(p) error_call_freep_instead p /* so that free doesn't exist anymore */

freep.c:

#include <stdlib.h>
#include "myprojectinclude.h"

#undef free
void freep(void **p)
{
    if (p) {
        free(*p);
        *p = NULL;
    }
}

main.c:

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

int main()
{
     char *buffer = malloc(2048);
     size_t buffer_size = 2048;

     /* ... lots of code involving reading lines, etc. */

     freep(&buffer);

     /* buffer is guaranteed to be NULL here */
}

При такой настройке двойное освобождение невозможно.Если мы сделаем

     freep(&buffer);
     freep(&buffer);

, все пойдет не так, потому что buffer равен NULL после первого вызова.(Обратите внимание, что передача NULL в free безопасна; иначе мы добавили бы проверку NULL, как я это делал десятилетия назад.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...