#c #c
#c #c
Вопрос:
Я запутался с символами и их соответствующими указателями в C .
Изначально я создал оболочку на C и пытаюсь сделать это на C . По какой-то причине я получаю память (coredump) при вызове memset()
и я не уверен, почему. Я запутался в указателях.
Например, в C следующее выполняется нормально:
int main() {
char *valid[1024];
while(1) {
//eliding other code
memset(valid, '', 1024);
}
}
это работает нормально.
Это то, что у меня сейчас есть в C :
int main () {
char valid[1024];
while(1){
memset(valid,'',1024);
}
}
По сути, тот же код для memset()
‘ing, но он сразу же вылетает. Все остальные функции моей программы закомментированы. Uncommeting memset()
предотвращает сброс ядра.
Что касается указателей, я знаю, что в C char *valid[1024]
это был бы указатель на постоянный массив символов, верно? Не уверен, почему *valid[1024]
работает в C, но не в C ? Но в данном случае я работаю char valid[1024]
на C , поэтому это изменяемый массив.
Комментарии:
1.
char *valid[1024]
!=
char valid[1024]
2.
char *valid[1024] would be a pointer to a constant char array right?
Неправильно. Это было бы 1024 указателя на символы.3. Проблема не в вызове
memset()
, который вызывает проблему. Массив содержит1024
символы, и вызовmemset()
во втором примере кода только устанавливает эти1024
символы равными нулю. Проблема в другом коде (который вы не показали) в вашей программе, который, предположительно, делает что-то нехорошее с указателем и вызывает неопределенное поведение. Довольно часто неопределенное поведение приводит к сбою в другой части программы, например, в вашем случае — при вызовеmemset()
, который сам по себе не вызывает неопределенного поведения.4. Можете ли вы опубликовать точный и полный код, который приводит к сбою, для вас, чтобы мы могли воспроизвести проблему? Подтвердите, что вы можете воспроизвести проблему со всем и только с тем кодом, который вы публикуете.
5. @spontida
char valid[1024]; memset(valid, '', 1024);
отлично работает на всех платформах. Ваша проблема в чем-то другом.
Ответ №1:
char *valid[1024];
Это массив из 1024 char*
— сам по себе он не является буфером символов. Это может указывать на другие буферы, но само по себе буфером не является. Это совершенно законно, но очень маловероятно, что на самом деле это то, что было задумано.
Ваш первый memset фактически удаляет только четверть этого массива (или меньше, в зависимости от того, компилируетесь ли вы как 32-разрядный или 64-разрядный); остальное остается неинициализированным. Также вряд ли предназначено.
char valid[1024];
Это массив из 1024 char
— стандартный буфер из 1024 символов, который действительно может содержать данные.
Memset для этого действительно будет работать правильно. Хотя вы можете заставить компилятор выполнить эквивалентный memset для вас, просто используя инициализацию значения:
char valid[1024] = {};
(В C вы также можете сделать это, но у вас должно быть 0
внутри фигурных скобок.)
Итак, что бы ни было на самом деле причиной вашего сбоя, это, скорее всего, в другом месте.
Комментарии:
1. В C бесконечный цикл без побочных эффектов имеет UB, поэтому, даже если код выглядит нормально, это не так.
2. Да, бесконечный цикл глуп, и я предположил, что это не имеет отношения к реальному вопросу, поэтому я не рассматриваю это здесь. Хотя это правда, что некоторые компиляторы агрессивно пытаются оптимизировать UB до безумия.
3. Поскольку в программе есть UB, бессмысленно искать причины сбоя в другом месте, когда уже представлена одна возможная причина. Возможно, это не единственная причина, но мы видим именно ее.
4. Спасибо, цикл был там только для того, чтобы подразумевать, что у меня были запущены другие вещи. Удалив все и просто оставив инициализацию char допустимой [1024 =; Я обнаружил, что это все еще вызывает проблему в среде, в которой я работал. Тем не менее, он отлично работает без каких-либо проблем на моем Mac. Спасибо, что разъяснили мои проблемы с знаниями указателей.
5. @spontida Массив указателей на буферы данных или строки. В C лучше использовать
std::string
вместоchar*
.