Я пытаюсь позволить переменной char*
указывать на строку mallo c, но происходит что-то действительно неправильное, и я имею дело с ошибкой сегментации.
Это вовлеченная часть моего кода, я попытался привести исполняемый пример, но с использованием сокета AF_ UNIX, боюсь, это не легко проверить.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdarg.h>
#define MSG_LEN 64
int vasprintf(char** str, const const char* format, va_list args) {
size_t size;
va_list tmp;
va_copy(tmp, args);
size = vsnprintf(NULL, 0, format, tmp);
va_end(tmp);
if (size == -1) {
return -1;
}
if ((*str = (char*)malloc(sizeof(char) * (size + 1))) == NULL) {
return -1;
}
size = vsprintf(*str, format, args);
return size;
}
int asprintf(char** str, const char* format, ...) {
size_t size;
va_list args;
if (str == NULL) {
return 1;
}
va_start(args, format);
size = vasprintf(str, format, args);
va_end(args);
return size;
}
typedef struct {
int socket;
struct sockaddr addr;
socklen_t addrlen;
} connection_t;
int connection_init(connection_t* connection, const char* address, const uint16_t port) {
if (!port) {
if ((connection->socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
return -1;
}
memset(&connection->addr, 'x', sizeof(connection->addr));
((struct sockaddr_un*) & connection->addr)->sun_family = AF_UNIX;
((struct sockaddr_un*) & connection->addr)->sun_path[0] = '\0';
strncpy(((struct sockaddr_un*) & connection->addr)->sun_path + 1, address, strlen(address));
connection->addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(address);
return 0;
}
}
int connetcion_connect(const connection_t* connection) {
if (connect(connection->socket, &connection->addr, connection->addrlen) == -1) {
return -1;
}
return 0;
}
int connection_send(const connection_t* connection, const char* buff) {
ssize_t len;
if ((len = send(connection->socket, buff, strlen(buff), 0)) == -1) {
return -1;
}
return len;
}
int connection_recv(const connection_t* connection, char** buff) {
ssize_t len;
if (((*buff) = (char*)malloc(sizeof(char) * (MSG_LEN + 1))) == NULL) {
return -1;
}
memset((*buff), 0, sizeof(char) * (MSG_LEN + 1));
len = recv(connection->socket, (*buff), MSG_LEN, 0);
if (len == -1 || len > MSG_LEN) {
free((*buff));
(*buff) = NULL;
return -1;
}
(*buff)[len] = 0;
/* Resize if string is shorter than len */
if (realloc((*buff), sizeof(char) * (strlen((*buff)) + 1)) == NULL) {
free((*buff));
(*buff) = NULL;
return -1;
}
return len;
}
int foo(char* query, char** result) {
connection_t con;
char* filename;
if (asprintf(&filename, "%s%s", getenv("HOME"), "/.directory/socket") == -1) {
return 1;
}
if (connection_init(&con, filename, 0) == -1) {
return 1;
}
free(filename);
if (connetcion_connect(&con) == -1) {
return 1;
}
if (connection_send(&con, query) == -1) {
return 1;
}
printf("Address %p in foo point to:\n", result);
printf("%p\n", *result);
if (connection_recv(&con, result) == -1) {
return 1;
}
printf("Address %p in foo point to:\n", result);
printf("%p\n", *result);
return 0;
}
int main(int argc, char *argv[]){
if (argc == 3 && !strncasecmp(argv[1], "hello", 5)) {
char* buff = NULL;
printf("Address %p in main point to:\n", &buff);
printf("%p\n", buff);
if(foo(argv[2], &buff)){
return 1;
}
printf("Address %p in main point to:\n", &buff);
printf("%p\n", buff);
printf("%s\n", buff);
}
return 0;
}
Ожидаемый результат:
Address "0x7ffd4c0c0d28" in main point to:
(nil)
Address "0x7ffd4c0c0d28" in foo point to:
(nil)
Address "0x7ffd4c0c0d28" in foo point to:
0x1bfa6a0
Address "0x7ffd4c0c0d28" in main point to:
0x1bfa6a0
Фактический результат:
Address "0x7ffd4c0c0d28" in main point to:
(nil)
Address "0x7ffd4c0c0d28" in foo point to:
(nil)
Address "0x7ffd4c0c0d28" in foo point to:
0x1bfa6a0
Address "0x7f74656b6367" in main point to:
Segmentation fault
Единственное возможное объяснение, которое я могу думать, это то, что я как-то повредил стек, если нужны другие ресурсы, пожалуйста, дайте мне знать, и я постараюсь предоставить их, как только возможно
Дополнительная информация:
Попробуйте printf("%s\n", *result)
непосредственно перед return 0
Я получаю ожидаемую строку.
Сервер использует ту же connection_*
функция для связи с клиентом.
Я включен на RHEL8.1 и собираю его с помощью g cc 8.3.1