Использование указателя, возвращаемого функцией, дает специальные символы (в C) [dубликат]

  SELECT * FROM myTable WHERE (Column1 = MyOtherValue) AND ((ColumnA = MyValue) ИЛИ (ColumnB = MyValue) ИЛИ (ColumnC = MyValue))  
4
задан random_guy 25 September 2009 в 06:54
поделиться

2 ответа

В вашем коде вы не возвращаете указатель на локальную структуру. Вы возвращаете указатель на буфер malloc () 'd, который будет находиться на куче.

Таким образом, совершенно безопасно.

Однако вызывающий (или вызывающий абонент или

Что небезопасно:

  char * foo () {  char bar [100];  // заполнять барную строку бар;  }  

Так как это возвращает указатель на кусок памяти, который находится в стеке, это локальная переменная - и, по возвращении, эта память больше не будет действительна.

Tinkertim ссылается на «статическое распределение бара и обеспечение взаимного исключения».

Конечно:

  char * foo () {static char bar [100];  // заполнять барную строку бар;  }  

Это будет работать так, что оно вернет указатель на статически выделенную панель буфера. Статическое выделение означает, что бар является глобальным.

Таким образом, выше не работают в многопоточной среде, где могут быть одновременные вызовы foo () [ ! d2]. Вам нужно будет использовать какой-то примитив синхронизации, чтобы два вызова foo () не топтались друг на друга. Есть много, много, примитивов синхронизации & amp; доступные шаблоны, что в сочетании с тем, что вопрос был о буфере malloc () ed, выдает такое обсуждение из области действия для этого вопроса.

Чтобы быть ясным: [ ! d16]

  // это распределение в стеке и не может быть безопасно возвращено char bar [100];  // это так же, как и выше;  не возвращай!  char * bar = alloca (100);  // это выделение в куче и ** может быть безопасно возвращено, но вы должны освободить () malloc (100);  // это глобальное или статическое распределение, которое есть только для каждого сеанса приложения // вы можете вернуть его безопасно, но вы не можете писать ему из нескольких потоков без // проблем с синхронизацией!  статический char bar [100];   
13
ответ дан bbum 15 August 2018 в 20:31
поделиться
  • 1
    +1, хотя вы можете подумать о том, чтобы пересмотреть небезопасный пример, чтобы быть в безопасности, путем статического выделения бара [] и указания необходимости взаимного исключения при вызове функции. Это сделало бы этот ответ очень полезным в архиве. – Tim Post♦ 25 September 2009 в 07:03
  • 2
    Просто чтобы быть ясным: malloc, как новый, выделяет пространство в куче, а не стек? Правильно ли я понял? – Amarghosh 25 September 2009 в 07:05
  • 3
    Благодарю. Время от времени меня путают со стеком и кучами. – random_guy 25 September 2009 в 07:08
  • 4
    Хорошее объяснение, но, может быть, примеры были бы лучше, если бы заменяли массивы фактическими структурами (и возвращали указатель), как в вопросе? – ahy1 25 September 2009 в 13:01

Подумайте об этом так: вы можете вернуть указатель из функции, если память, выделенная этому указателю, не является локальной для этой функции (то есть в кадре стека этого экземпляра этой функции - если быть точным)

2
ответ дан Ashwin 15 August 2018 в 20:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: