копирование данных в строку внутри структуры в C дает ошибку сегментации - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь скопировать строку (myipaddr) в другую строку (в середине), которая объявлена ​​внутри структуры. Я не могу принять любой другой способ, поскольку я должен использовать это в другом более крупном коде.

Я получаю ошибку сегментации в строке memcpy, в то время как та же строка (в середине), если я объявляю внутри функции char * my_ip, работает нормально.

main.c

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>

 #include <sys/ioctl.h>
 #include <net/if.h>
 #include "private.h"

char *my_ip(char *myniccard, char *myipaddr) {

  address_t *accessor = NULL;

      int fd;
      struct ifreq ifr;

      myipaddr[0]=0;

      fd = socket(AF_INET, SOCK_DGRAM, 0);

      /* I want to get an IPv4 IP address */
      ifr.ifr_addr.sa_family = AF_INET;

      /* I want IP address attached to "eth0" */
      //strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
      strncpy(ifr.ifr_name, myniccard, IFNAMSIZ-1);

      ioctl(fd, SIOCGIFADDR, &ifr);

      close(fd);


      /* display result */
      sprintf(myipaddr,"%s"
        , inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));

      memcpy(accessor->middle, myipaddr, 16 * sizeof (char));   // here is segmentation fault.
      printf("Buffer :%s\n",accessor->middle);

      return (myipaddr);
      }   // my_ip



 int main (){

     char addr[22];
     char *card = "wl1";

     char *ip = (char *)malloc(sizeof (char));
     ip = my_ip(card, addr);
     free (ip);

     return 0;
     }

private.h

#ifndef FILE_PRIVATE_HEADER
#define FILE_PRIVATE_HEADER

#include <sys/socket.h> // inet_aton
#include <netinet/in.h> // inet_aton
#include <arpa/inet.h>  // inet_aton
#include "queue.h"
#include "bstrlib.h"

#define PGW_NUM_UE_POOL_MAX 16

typedef struct data {


char middle[PGW_NUM_UE_POOL_MAX];


}address_t;

#endif

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

accessor - это указатель NULL типа address_t:

address_t *accessor = NULL;

и здесь вы пытаетесь получить доступ к его члену middle, используя указатель NULL:

  memcpy(accessor->middle, myipaddr, 16 * sizeof (char));   // here is segmentation fault.

Следовательно, вы получаете ошибку сегментации в этом утверждении.

Кроме того, в вашем коде есть несколько других проблем.
Здесь вы выделяете память для ip:

     char *ip = (char *)malloc(sizeof (char));

и в следующем утверждении:

     ip = my_ip(card, addr);

Вы присваиваете my_ip возвращаемое значение функции ip. Таким образом, вы теряете ссылку на память, выделенную в предыдущем выражении, что является утечкой памяти.
После этого вы делаете

free (ip);

ip будет указывать на myipaddr, возвращенную функцией my_ip, которая является ничем иным, как адресом переменной локального массива addr, переданной функции my_ip. Это означает, что вы звоните free по адресу локальной переменной. Вы можете вызывать только free() что-то, что вы получили из функции malloc(), calloc() или realloc(), иначе это вызывает неопределенное поведение.

0 голосов
/ 29 июня 2018

Функция my_ip возвращает указатель на первый символ addr. Этот указатель не то, что вы можете free.

Давайте возьмем эти три строки:

 char *ip = (char *)malloc(sizeof (char));
 ip = my_ip(card, addr);
 free (ip);

И возьми их по одному:

  1. char *ip = (char *)malloc(sizeof (char));

    Эта строка определяет переменную ip и инициализирует ее для указания на однобайтовый , возвращаемый вызовом malloc.

  2. ip = my_ip(card, addr);

    Этот переназначает указатель, поэтому он больше не указывает на память, возвращаемую malloc. Вместо этого теперь он будет указывать на первый символ addr (поскольку именно это возвращает my_ip).

  3. free (ip);

    Теперь вы фактически пытаетесь сделать free(&addr[0]), что неверно.

Простое решение - не звонить ни malloc, ни free.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...