포인터가 여전히 해제된 메모리 영역을 가르키고 있다면 이러한 포인터를 댕글링 포인터라고 한다. 댕글링 포인터가 가리키는 메모리는 더는 유효하지 않다. 댕글링 포인터는 조숙한 해제, 너무 급한 해제라고 부르기도 한다.
댕글링 포인터의 사용은 아래 목록에 나열된 문제를 포함한 다양한 문제를 야기한다.
free 함수로 메모리를 해제한 후에도 변수는 여전히 메모리의 주소를 가리고 있다. 이 메모리는 힙관리자에 의해 재사용되거나 기존의 정수가 아닌 다른 타입으로도 사용될 수 있다. free 함수를 호출하면 원래 pi 포인터가 가리키고 있던 주소에 위치한 메모리는 해제되며 다시 사용할 수 없다. 그러나 대부분의 런타임 시스템에서 해제 뒤에 발생하는 메모리의 접근이나 변경을 막지 않는다.
BUFFER_SIZE가 스택의 저장공간보다 크게 입력되어 들어온다면 Segmentation fault 오류가 발생될 것이다.
스택의 저장공간의 사이즈는 운영체제마다 상이하다.
open_max를 사용하게 될 경우의 문제점
#include "get_next_line.h"
#include <stdio.h>
char *ft_substr(char *s, unsigned int start, size_t len)
{
char *substr;
size_t s_len;
size_t i;
s_len = ft_strlen(s);
if (s_len <= start)
{
substr = (char *)malloc(sizeof(char));
if (!substr)
return (NULL);
substr[0] = '\0';
return (substr);
}
if (s_len - start < len)
len = s_len - start;
substr = (char *)malloc(len + 1);
if (!substr)
return (0);
i = -1;
while (++i < len)
substr[i] = s[start++];
substr[i] = '\0';
return (substr);
}
// static char *ft_add(char **backup, char *buf)
// {
// char *tmp;
// tmp = ft_strjoin(*backup, buf);
// if (!tmp)
// return (0);
// *backup = tmp;
// free(tmp);
// tmp = NULL;
// return (0);
// }
// static char *ft_add(char **backup, char *buf)
// {
// char *tmp;
// tmp = *backup;
// *backup = ft_strjoin(tmp, buf);
// if (!(*backup))
// {
// free(tmp);
// return (0);
// }
// free(tmp);
// return (0);
// }
static char *ft_add(char *backup, char *buf)
{
char *tmp;
tmp = ft_strjoin(backup, buf);
if (!tmp)
{
free(backup);
return (0);
}
free(backup);
return (tmp);
}
static char *ft_cut(char **backup)
{
char *tmp;
char *ret_read;
int i;
i = ft_strchr_index(*backup, '\n');
if (i == -1)
i = ft_strchr_index(*backup, '\0');
ret_read = ft_substr(*backup, 0, i + 1);
if (!ret_read)
{
free(*backup);
*backup = NULL;
return (0);
}
tmp = *backup;
*backup = ft_substr(*backup, i + 1, ft_strlen(*backup));
if (!tmp)
{
free(*backup);
*backup = NULL;
return (0);
}
free(tmp);
return (ret_read);
}
int read_check(int read, char **backup)
{
if (read == -1 || (read == 0 && !(**backup)))
{
free(*backup);
*backup = NULL;
return (1);
}
return (0);
}
char *get_next_line(int fd)
{
static char *backup;
char buf[BUFFER_SIZE + 1];
int readed;
if (!backup)
backup = ft_strdup("");
if (!backup)
return (0);
while (ft_strchr_index(backup, '\n') < 0)
{
readed = read(fd, buf, BUFFER_SIZE);
if (read_check(readed, &backup))
{
free(backup);
backup = NULL;
return (0);
}
buf[readed] = '\0';
if (readed == 0 && (*backup))
break ;
backup = ft_add(backup, buf);
if (!backup)
return (0);
}
return (ft_cut(&backup));
}
// #include <stdio.h>
// int main(void)
// {
// int fd;
// char *line;
// fd = 0;
// fd = open("./test",O_RDONLY);
// line = get_next_line(fd);
// printf("|%s|", line);
// line = get_next_line(fd);
// printf("|%s|", line);
// line = get_next_line(fd);
// printf("|%s|", line);
// line = get_next_line(fd);
// printf("|%s|", line);
// line = get_next_line(fd);
// printf("|%s|", line);
// line = get_next_line(fd);
// printf("|%s|", line);
// line = get_next_line(fd);
// printf("|%s|", line);
// return (0);
// }