Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.04.2012, 16:01   #1
demoniqus
Пользователь
 
Регистрация: 13.04.2012
Сообщений: 12
По умолчанию Переполнение буфера в функции

Вот код:
Код:
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/postgresql/libpq-fe.h>
#include </usr/include/postgresql/pg_config.h>
#include <string.h>


char *getColNumFromTable(char schema[], char table[]);

int main() {
char schema_str[] = "bil";
char* schema = schema_str;
char table_str[] = ".connect";
char* table = table_str;

printf("\n first_arg = %s\n", schema_str);
printf("\n first_arg = %i\n", *schema_str);
printf("\n first_arg = %s\n", schema);
printf("\n * = %s\n", schema);
getColNumFromTable(schema, table);
}

char *getColNumFromTable(char schema[], char table[]) {
strcat(schema , table);
printf("\n\n function getColNumFromTable  %s \n\n", schema);
printf("\n\n%s%s\n\n", schema, table);
}
функция getColNumFromTable получает два строковых параметра и должна их объединить, а затем вывести на печать. Собственно вывод на печать происходит. Но также я получаю сообщение о переполнении буфера с вылетом на ошибке 134, если суммарная длина двух строк превышает 12 видимых символов. Подскажите, в чем моя ошибка?
demoniqus вне форума Ответить с цитированием
Старый 17.04.2012, 16:20   #2
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
char schema_str[] = "bil";
память была выделена статически и изменить ее нельзя, а вы пытаетесь туда еще и строку загнать...

а если так?
Код:
char schema_str[256] = "bil";
counter вне форума Ответить с цитированием
Старый 17.04.2012, 16:25   #3
demoniqus
Пользователь
 
Регистрация: 13.04.2012
Сообщений: 12
По умолчанию

Цитата:
Сообщение от counter Посмотреть сообщение
память была выделена статически и изменить ее нельзя, а вы пытаетесь туда еще и строку загнать...

а если так?
Код:
char schema_str[256] = "bil";
вариант прокатывает, но не хотелось бы делать привязку к какому-то числу, ведь где-нибудь можно и вылезти за его пределы случайно...
а с другой стороны не хотелось бы впустую выделять байты, если они не будут задействованы...
Подскажите, в таком варианте нет подвохов:
Код:
char schema_str[(sizeof("billing") + sizeof(".connections") + 2)] = "billing";
И, если я верно понимаю, то при конкатенации строк нулевой символ в конце первой строки не удаляется?

Последний раз редактировалось demoniqus; 17.04.2012 в 16:45.
demoniqus вне форума Ответить с цитированием
Старый 17.04.2012, 16:43   #4
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от demoniqus Посмотреть сообщение
вариант прокатывает
это рабочий вариант!
Цитата:
Сообщение от demoniqus Посмотреть сообщение
но не хотелось бы делать привязку к какому-то числу, ведь где-нибудь можно и вылезти за его пределы случайно...
и
Цитата:
Сообщение от demoniqus Посмотреть сообщение
char schema_str[(sizeof("billing") + sizeof(".connections") + 2)] = "billing";
вроде как одно и тоже
Цитата:
Сообщение от demoniqus Посмотреть сообщение
а с другой стороны не хотелось бы впустую выделять байты, если они не будут задействованы...
У вас PDP-11 ? Что вам так жалко пару байт? К тому же, если вы знаете размер данных, с которыми будете работать, то в чем загвоздка?
Код:
#define MAX_BUFFER_LENGTH  512
...

char str[MAX_BUFFER_LENGTH];
counter вне форума Ответить с цитированием
Старый 17.04.2012, 17:04   #5
demoniqus
Пользователь
 
Регистрация: 13.04.2012
Сообщений: 12
По умолчанию

Цитата:

У вас PDP-11 ? Что вам так жалко пару байт? К тому же, если вы знаете размер данных, с которыми будете работать, то в чем загвоздка?
Я заранее не знаю, какой длины будут строки - это может быть и 3 символа и 333...
Свой вариант немножко перепишу
Код:
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/postgresql/libpq-fe.h>
#include </usr/include/postgresql/pg_config.h>
#include <string.h>

char *getColNumFromTable(char schema[], char table[], char col_name[]);

int main() {
char sch_str[] = "billing";// значение будет динамическим
char table_str[] = ".connection";// значение будет динамическим
char col_name_str[] = ".connection_column";// значение будет динамическим
char schema_str[(sizeof(sch_str) + sizeof(table_str) + sizeof(col_name_str))] = "";
strcat(schema_str, sch_str);

char* schema = schema_str;
char* col_name = col_name_str;
char* table = table_str;

printf("\n first_arg = %s\n", schema_str);
printf("\n first_arg = %i\n", *schema_str);
printf("\n sizeof = %lu\n", sizeof(schema_str));
printf("\n first_arg = %s\n", schema);
printf("\n * = %s\n", schema);
getColNumFromTable(schema, table, col_name);
}

char *getColNumFromTable(char schema[], char table[], char col_name[]) {
strcat(schema , table);
strcat(schema , col_name);
printf("\n\n function getColNumFromTable  %s \n\n", schema);
printf("\n\n function getColNumFromTable sizeof %lu \n\n", sizeof(schema));
printf("\n\n%s%s\n\n", schema, table);
}
Однако я не понимаю, как тут все работает... По идее, чтобы слепить три переменные, нужно выделить под них место, равное сумме их sizeof'ов, т.е.
char schema_str[(sizeof(sch_str) + sizeof(table_str) + sizeof(col_name_str))] = "";
однако и вариант
char schema_str[(sizeof(sch_str) + 5)] = "";
работает, хотя количество символов в трех переменных явно больше...
И почему в функции getColNumFromTable печатается sizeof = 8?
Цитата:
Код:
#define MAX_BUFFER_LENGTH  512
...

char str[MAX_BUFFER_LENGTH];
Мне еще далеко до определения костант...))))

Последний раз редактировалось demoniqus; 17.04.2012 в 17:08.
demoniqus вне форума Ответить с цитированием
Старый 17.04.2012, 17:22   #6
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от demoniqus Посмотреть сообщение
Я заранее не знаю, какой длины будут строки - это может быть и 3 символа и 333...
Динамическое выделение памяти используйте.
Цитата:
Сообщение от demoniqus Посмотреть сообщение
По идее, чтобы слепить три переменные, нужно выделить под них место, равное сумме их sizeof'ов
Не совсем. Этот sizeof не мешало бы еще и на количество элементов умножить. В Си это работает, потому что sizeof(char) равен 1 байт, поэтому и sizeof(указатель на строку) вернет длину строки.
counter вне форума Ответить с цитированием
Старый 17.04.2012, 18:00   #7
demoniqus
Пользователь
 
Регистрация: 13.04.2012
Сообщений: 12
По умолчанию

Цитата:
Сообщение от counter Посмотреть сообщение
Динамическое выделение памяти используйте.
Вот я это и пытаюсь сделать, да только не понимаю, сколько ж нужно ее выделить...
работает даже так:
Код:
char *getColNumFromTable(char table[], char col_name[], char schema[]) {
char result[41] = "";

printf("\n sizeof table %lu %s \n", sizeof(table), table);
printf("\n sizeof col_name %lu %s \n", sizeof(col_name), col_name);
printf("\n sizeof schema %lu %s\n", sizeof(schema), schema);
strcat(result , schema);
strcat(result , table);
strcat(result , col_name);
printf("\n\n RESULT function getColNumFromTable sizeof %lu  %s \n\n", sizeof(result), result);
}
хоть я и задал сразу для result размер 41, но тем не менее, в него без проблем добавились три строки общей длиной 46...
Цитата:
Не совсем. Этот sizeof не мешало бы еще и на количество элементов умножить. В Си это работает, потому что sizeof(char) равен 1 байт, поэтому и sizeof(указатель на строку) вернет длину строки.
у меня sizeof вроде нормально отрабатывает и для кириллицы, считая ее двухбайтовой (т.е. sizeof("ааа") = 7)...

Последний раз редактировалось demoniqus; 17.04.2012 в 18:21.
demoniqus вне форума Ответить с цитированием
Старый 17.04.2012, 18:16   #8
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от demoniqus Посмотреть сообщение
Вот я это и пытаюсь сделать, да только не понимаю, сколько ж нужно ее выделить...
Что-то не видно этих попыток.
Цитата:
Сообщение от demoniqus Посмотреть сообщение
работает даже так:
...
хоть я и задал сразу для result размер 1, но тем не менее, в него без проблем добавились три строки общей длиной 46...
...
И еще где-то тут ошибка сегментации затесалась...
Да тут что угодно будет. Бред это! Вы так записываете в память, которая может быть занята в любой момент другим процессом (или даже вашим) и тогда все рухнет!
counter вне форума Ответить с цитированием
Старый 17.04.2012, 18:29   #9
demoniqus
Пользователь
 
Регистрация: 13.04.2012
Сообщений: 12
По умолчанию

Цитата:
Сообщение от counter Посмотреть сообщение
Что-то не видно этих попыток.
Я просто не стал выкладывать все нежизнеспособные попытки, а так я испробовал в частности все варианты result от 0 до 46...
Цитата:
Да тут что угодно будет. Бред это! Вы так записываете в память, которая может быть занята в любой момент другим процессом (или даже вашим) и тогда все рухнет!
Вы успели ответить прежде, чем я успел подправить свои слова... вместо 1 получилось 41 и тогда ошибка сегментации исчезла. Однако я пока не понимаю, почему 41, а не общая длина в 46... если только последние 5 байт, как вы говорите, могут переопределиться в любой момент любым другим процессом, если их принудительно не выделить result[46] (или точнее result[(sizeof(...) + sizeof(...) + ...)])
demoniqus вне форума Ответить с цитированием
Старый 17.04.2012, 18:52   #10
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от demoniqus Посмотреть сообщение
Я просто не стал выкладывать все нежизнеспособные попытки, а так я испробовал в частности все варианты result от 0 до 46...
в этом что-то есть

Динамическое выделение памяти: calloc, malloc/free; new/delete - читаем разбираемся.
counter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переполнение stas45rus Паскаль, Turbo Pascal, PascalABC.NET 1 11.01.2012 20:54
переполнение буфера goluzov Общие вопросы C/C++ 21 28.11.2011 09:04
Как подменить адрес возврата функции func на адрес функции f используя переполнение буфера buf и функции gets dmitrii6120 Помощь студентам 6 14.11.2011 20:10
переполнение буфера Dimarik Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 13.07.2011 02:24
Переполнение стека Ake Паскаль, Turbo Pascal, PascalABC.NET 3 30.05.2009 22:39