Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка сегментации при использовании sprintf / 12 сообщений из 12, страница 1 из 1
06.10.2014, 18:49
    #38768347
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
Добрый день.

имеется функция:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
void *thread_func(void *arg)
{
	int loc_id = (int) arg;
	//char loc_id_ch = (char) loc_id;
	MYSQL f_mysql;                            // Дескриптор соединения
	MYSQL_RES *f_res;                         // Дескриптор результирующей таблицы
	MYSQL_ROW f_row;
	f_mysql = db_connect();
	char f_query;
	sprintf(&f_query,  "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);
	f_res = db_resource(f_mysql, &f_query);
	if (mysql_num_rows(f_res) > 0)
	{
		f_row = mysql_fetch_row(f_res);
		printf("UID = %s \n", f_row[1]);
	} else {
		printf("NO ROWS");
	}
	mysql_free_result(f_res); // Очищаем результаты
	mysql_close(&f_mysql); // Закрываем соединение
	sleep(1);
	return NULL;
}


все она хорошо работала, пока не вставил вот такую строку:
sprintf(&f_query, "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);

после этого выдает следующее при запуске приложения:

Код: plaintext
1.
2.
3.
4.
5.
calligraff@calligraff-deb:~$ g++ -Wall -Wextra -Werror -o prog `mysql_config --cflags` main.cpp `mysql_config --libs`
calligraff@calligraff-deb:~$ ./prog
UID = 28.76735D050000
Ошибка сегментирования
calligraff@calligraff-deb:~$

Помогите пожалуйста.

P.S. программирую на С++ не более 3 дней.

Спасибо.

ниже представлен весь код программы (на всякий случай):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <mysql/mysql.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;

MYSQL db_connect()
{
	// Описание дескрипторов
	MYSQL mysql;
	// Описание переменных
	char host[] = "localhost";             // Хост
	char user[] = "user1";             // Пользователь
	char passwd[] = "passwd1";     // Пароль
	char db[] = "base1";           // Название базы данных
	int port = 3306;                        // Порт

	// Инициализация
	mysql_init(&mysql);

	// Соединение
	if (!mysql_real_connect(&mysql, host, user, passwd, db, port, NULL, 0))
	{
		fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql));
	} else {
		//printf("Deamon connect to database is ok.\n");
	}

	return mysql;
}

MYSQL_RES *db_resource(MYSQL mysql, const char query[])
{
	// Описание дескрипторов
	MYSQL_RES *res;
	if (mysql_query(&mysql, query) > 0) // запорс. Если ошибок нет, то продолжаем работу
	{
		// Если была ошибка, ...
		printf("%s", mysql_error(&mysql));  // ... вывдем ее
		return 0; // и завершим работу
	}

	res = mysql_store_result(&mysql); // Берем результат,

	return res;
}

void *thread_func(void *arg)
{
	int loc_id = (int) arg;
	//char loc_id_ch = (char) loc_id;
	MYSQL f_mysql;                            // Дескриптор соединения
	MYSQL_RES *f_res;                         // Дескриптор результирующей таблицы
	MYSQL_ROW f_row;
	f_mysql = db_connect();
	char f_query;
	sprintf(&f_query,  "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);
	f_res = db_resource(f_mysql, &f_query);
	if (mysql_num_rows(f_res) > 0)
	{
		f_row = mysql_fetch_row(f_res);
		printf("UID = %s \n", f_row[1]);
	} else {
		printf("NO ROWS");
	}
	mysql_free_result(f_res); // Очищаем результаты
	mysql_close(&f_mysql); // Закрываем соединение
	sleep(1);
	return NULL;
}

void start_thread(MYSQL_RES *res)
{
	// Описание дескрипторов
	MYSQL_ROW row;

	pthread_attr_t threadAttr;
	pthread_attr_init(&threadAttr);
	pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);

	unsigned num_rows = mysql_num_rows(res); //***** и количество строк.

	pthread_t thread[num_rows];

	int id[num_rows];
	
	for (unsigned i = 0; i < num_rows; i++)
	{
		row = mysql_fetch_row(res);
		id[i] = atoi(row[0]);
		pthread_create(&thread[i], &threadAttr, thread_func, (void*)id[i]);
	}

}

int main(){
	// Описание дескрипторов
	MYSQL mysql;				// Дескриптор соединения
	MYSQL_RES *res;				// Дескриптор результирующей таблицы

	mysql = db_connect();
	res = db_resource(mysql, "SELECT id, uid FROM sensors WHERE enabled = 1");
	start_thread(res);
	mysql_free_result(res); // Очищаем результаты
	mysql_close(&mysql); // Закрываем соединение

	sleep(10);

	return 0;
}
...
Рейтинг: 0 / 0
06.10.2014, 18:54
    #38768351
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
fs99,

Код: plaintext
1.
int loc_id = (int) arg;


Это вообще подозрительно -- присваивать адрес в качестве значения переменной типа int

Код: plaintext
1.
int loc_id = * arg;


Так правильнее.

Код: plaintext
1.
2.
char f_query;
sprintf(&f_query,  "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);



Вы пытаетесь всю строчку запихать в 1 символ
Правильнее было бы

Код: plaintext
1.
2.
char f_query[256]; // размер сами подбирайте или юзайте оператор new
sprintf(f_query,  "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);
...
Рейтинг: 0 / 0
06.10.2014, 18:59
    #38768354
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
при замене
Код: plaintext
1.
int loc_id = (int) arg;


на
Код: plaintext
1.
int loc_id = * arg;



результат компилирования:
Код: plaintext
1.
2.
main.cpp: In function ‘void* thread_func(void*)’:
main.cpp:55:17: error: ‘void*’ is not a pointer-to-object type

-----------------------------------------

при
Код: plaintext
1.
2.
char f_query[256]; // размер сами подбирайте или юзайте оператор new
sprintf(f_query,  "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);



результат:

Код: plaintext
1.
2.
main.cpp: In function ‘void* thread_func(void*)’:
main.cpp:66:39: error: cannot convert ‘char (*)[256]’ to ‘const char*’ for argument ‘2’ to ‘MYSQL_RES* db_resource(MYSQL, const char*)’

на самом деле как только не пробовал - всегда какая-нить ошибка.
...
Рейтинг: 0 / 0
06.10.2014, 19:16
    #38768364
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
Вариантов нет???
...
Рейтинг: 0 / 0
06.10.2014, 19:21
    #38768369
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
прошу прощения!

Код: plaintext
1.
2.
char f_query[256]; // размер сами подбирайте или юзайте оператор new
sprintf(f_query,  "SELECT id, uid FROM sensors WHERE enabled = 1 AND id = %d", loc_id);


верное решение.. там ошибка о другом выскакивала.

а вот int loc_id = * arg; нехотит
...
Рейтинг: 0 / 0
06.10.2014, 19:27
    #38768375
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
fs99,

Ну так сделай reinterpret_cast:

Код: plaintext
1.
int loc_id = * reinterpret_cast< int * >( arg );
...
Рейтинг: 0 / 0
06.10.2014, 19:29
    #38768377
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
NekZfs99,

Ну так сделай reinterpret_cast:

Код: plaintext
1.
int loc_id = * reinterpret_cast< int * >( arg );



Ошибка сегментирования
...
Рейтинг: 0 / 0
06.10.2014, 19:33
    #38768380
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
fs99,
Вы гаданием что-ли программируете?

Вот тут вы преобразуете int в void*
Код: plaintext
1.
pthread_create(&thread[i], &threadAttr, thread_func, (void*)id[i]);



Значит тут надо обратно преобразовать
Код: plaintext
1.
int loc_id = (int)arg;



Хотя конечно по большому счету никто не обещал что void* может вместить int или наоборот.
Но на практике указатель обычно не меньше целого. Так что сойдет.
...
Рейтинг: 0 / 0
06.10.2014, 19:39
    #38768386
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
:)


спасибо.

Я же говорил, всего 3 дня на Си пытаюсь что-то написать :)
...
Рейтинг: 0 / 0
06.10.2014, 20:17
    #38768406
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
Вот так вот. С++ за 3 дня. С потоками.
...
Рейтинг: 0 / 0
06.10.2014, 20:38
    #38768418
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
maytonВот так вот. С++ за 3 дня. С потоками.
А я считаю - правильно, сразу в бой. Чего рассусоливать :)
Тут основная ошибка - что программа в стиле С, хотя используется компилятор С++
...
Рейтинг: 0 / 0
06.10.2014, 21:50
    #38768476
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка сегментации при использовании sprintf
Я-бы три года посоветовал. Покодить что-то без потоков. Как-то вот так.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка сегментации при использовании sprintf / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]