powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка сегментации при использовании sprintf
12 сообщений из 12, страница 1 из 1
Ошибка сегментации при использовании sprintf
    #38768347
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день.

имеется функция:
Код: 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
Ошибка сегментации при использовании sprintf
    #38768351
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Ошибка сегментации при использовании sprintf
    #38768354
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
при замене
Код: 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
Ошибка сегментации при использовании sprintf
    #38768364
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариантов нет???
...
Рейтинг: 0 / 0
Ошибка сегментации при использовании sprintf
    #38768369
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
прошу прощения!

Код: 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
Ошибка сегментации при использовании sprintf
    #38768375
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99,

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

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

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

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



Ошибка сегментирования
...
Рейтинг: 0 / 0
Ошибка сегментации при использовании sprintf
    #38768380
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Ошибка сегментации при использовании sprintf
    #38768386
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
:)


спасибо.

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


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