when
- 23.03.13 월 21:20 ~ 22:50
- 23.03.23 목 15:00 ~ 18:00 / 19:30 ~ 23:00
- 23.03.25 토 15:30 ~ 18:00 / 21:00 ~ 24:00
- 23.03.26 일 00:00 ~ 04:00 / 10:00 ~ 16:00
- 23.03.27 월 21:00 ~ 24:30
- 23.04.02 일 13:30 ~ 02:00
- 23.04.05 수 20:00 ~ 02:00 (평가)
- 23.04.07 금 11:00 ~ 16:00 (평가)
내용 | |
---|---|
프로그램 이름 | libft.a |
제출 파일 | ft_*.c, libft.h, Makefile |
Makefile | NAME, all, clean, fclean, re |
외부 함수 | malloc |
norm error 금지
segmetation fault, bus error, double free 금지
heap에 동적 할당된 메모리 해제 (메모리 누수 방지)
Makefile
전역 변수 사용 금지
library를 만들기 위해서 ar command 사용
함수 구현 시 앞에 ft_ 붙이기
restrict 키워드는 C99에서 정의되므로 사용 금지
int ft_isalpha(int c)
{
if ((('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z')))
return (1);
return (0);
}
📖 참고 📖 c가 int형인 이유
- 대문자와 소문자 이외에 EOF 값 또는 unsigned char 값 표현해야함
- char형은 -128 ~ 127 범위이므로 EOF(-1) 또는 unsigned char 처리 불가능
int ft_isdigit(int c)
{
if ('0' <= c && c <= '9')
return (1);
return (0);
}
int ft_isalnum(int c)
{
if (('0' <= c && c <= '9')
|| (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')))
return (1);
return (0);
}
int ft_isascii(int c)
{
if (0 <= c && c <= 127)
return (1);
else
return (0);
}
int ft_isprint(int c)
{
if (32 <= c && c <= 126)
return (1);
return (0);
}
#include "libft.h"
size_t ft_strlen(const char *s)
{
size_t i;
i = 0;
while (*(s + i) != '\0')
i++;
return (i);
}
📖 참고 📖 size_t
- 개념
- c언어에서 임의의 객체가 가질 수 있는 최대 크기
- 부호 없는 정수와 동일 (unsigned int)
- sizeof 연산자의 반환 타입으로 사용됨
- 사용 이유
- 안전한 크기 타입을 제공하기 위해 사용
- 시스템에서 주소 지정이 가능한 메모리 영역과 일치하는 크기를 선언하여 이식 가능한 방법을 제공할 목적
- 출력
- %zu 지정자 사용
- %u, %lu 지정자 대체 가능
- 출력 시 잘못 된 형식 지정자를 선택하며 예상치 못한 값 출력됨
- 참고 사이트
📖 참고 📖 const
- 개념
- 변수를 선언할 때 변수의 데이터형 앞에 const 키워드를 지정하면 변경 불가능
- 상수와 다르게 변수이기에 메모리에 할당이 되며, 단순 값을 변경 못하게함
- 변수처럼 값 초기화 필요
- 사용 이유
- 전달 받은 내용을 바꾸지 않을 목적
- 값 변경시 형 변환을 사용 가능
- 참고 사이트
📖 참고 📖 char const vs const char
- 개념
- const char 타입의 포인터로 같은 의미
- 포인터는 가리키는 메모리의 내용이 변경될 수 없음을 나타내기 위해 사용
- const 키워드는 변수 & 포인터 모두 수정 가능
- 차이점
- char const * : char 타입을 가리키는 포인터의 값을 변경할 수 없는 것 (함수 내에서 해당 포인터 수정 가능)
- const char * : 포인터를 가리키는 값이 변경될 수 없는 char 타입 (함수 내에서 해당 포인터 수정x)
#include "libft.h"
void *ft_memset(void *b, int c, size_t len)
{
unsigned char *mem;
unsigned char value;
mem = (unsigned char *)b;
value = (unsigned char)c;
while (len-- > 0)
*mem++ = value;
return (b);
}
// Main Example
int intarr[10];
char chararr[10];
memset(intarr, 0, sizeof(intarr));
//memset(intarr, 0, sizeof(int) * 10);
memset(chararr, 'A', sizeof(chararr));
// intarr == '0 0 0 0 0 ...'
// chararr == "AAAAA..."
📖 참고 📖 void, unsigned char 포인터 캐스팅 이유
- void 포인터 연산은 호환성을 위해 사용하지 않음
- 메모리를 1바이트씩 접근하려면 unsigned char* 사용
- 포인터는 주솟값이라 부호를 쓰지 않음
📖 참고 📖 int를 unsigend char로 바꿔야 하는 이유
- 시스템에 따라서 문자가 1/2/4바이트일 수도 있는데, 문자를 1바이트로 가정하고 char/unsigned char로 사용할 경우 문자를 2/4바이트로 정의해야하는 시스템에서 사용 불가
- c 값을 unsinged char 로 변환되어 1바이트의 메모리에 값을 집어넣어서 사용
- 참고 사이트
#include "libft.h"
void ft_bzero(void *s, size_t n)
{
unsigned char *b;
b = (unsigned char *)s;
while (n-- > 0)
*b++ = 0;
}
#include "libft.h"
void *ft_memcpy(void *dst, const void *src, size_t n)
{
unsigned char *d;
unsigned char *s;
d = (unsigned char *)dst;
s = (unsigned char *)src;
if (!d && !s)
return (NULL);
while (n > 0)
{
*d++ = *s++;
n--;
}
return (dst);
}
📖 참고 📖 restrict 키워드
- 개념
- C99 이후의 버전에서 사용 가능
- restrict 키워드가 붙은 포인터가 가리키는 객체는 다른 포인터가 가리키지x
- 프로그래머가 컴파일러에게 메모리 접근에 대한 최적화 요청하여 빠른 성능 보장 (동일한 메모리 접근이 없다는 것을 보장해야함)
특정 메모리 영역에 접근 할 수 있는 포인터가 단 하나임을 보장
하는 키워드- 다른 restrict 변수들과 같은 공간을 가리키지 않는다고 컴파일러에게 알려주는 것!
#include "libft.h"
void *ft_memmove(void *dst, const void *src, size_t len)
{
unsigned char *temp;
unsigned char *value;
temp = (unsigned char *)dst;
value = (unsigned char *)src;
if (!dst && !src)
return (NULL);
if (len < 0)
len *= -1;
if (temp < value)
while (len-- > 0)
*temp++ = *value++;
else if (temp > value)
while (len-- > 0)
*(temp + len) = *(value + len);
return (dst);
}
#include "libft.h"
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
size_t len_s;
len_s = ft_strlen(src);
if (dstsize == 0)
return (len_s);
while (*src != '\0' && (dstsize - 1) > 0)
{
*dst++ = *src++;
dstsize--;
}
*dst = '\0';
return (len_s);
}
#include "libft.h"
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
{
size_t i;
size_t len_d;
size_t len_s;
i = 0;
len_d = ft_strlen(dst);
len_s = ft_strlen(src);
if (dstsize < len_d + 1)
return (dstsize + len_s);
if (dstsize >= len_d + 1)
{
while (*(src + i) != '\0' && len_d + i + 1 < dstsize)
{
*(dst + len_d + i) = *(src + i);
i++;
}
*(dst + len_d + i) = '\0';
}
return (len_d + len_s);
}
#include "libft.h"
int ft_strncmp(const char *s1, const char *s2, size_t n)
{
unsigned char *c1;
unsigned char *c2;
c1 = (unsigned char *)s1;
c2 = (unsigned char *)s2;
while ((*c1 || *c2) && n > 0)
{
if (*c1 != *c2)
return (*c1 - *c2);
c1++;
c2++;
n--;
}
return (0);
}
int ft_toupper(int c)
{
if ('a' <= c && c <= 'z')
return (c - 32);
return (c);
}
int ft_tolower(int c)
{
if ('A' <= c && c <= 'Z')
return (c + 32);
return (c);
}
char *ft_strchr(const char *s, int c)
{
while (*s)
{
if (*s == (char)c)
return ((char *)s);
s++;
}
if ((char)c == '\0')
return ((char *)s);
return (0);
}
#include "libft.h"
char *ft_strrchr(const char *s, int c)
{
size_t len;
len = ft_strlen(s) + 1;
while (len != 0)
{
if (s[len - 1] == (char)c)
return ((char *)&s[len - 1]);
len--;
}
return (0);
}
unsigned char로 형변환된 c가 나타나는 곳을 위치시킴
#include "libft.h"
void *ft_memchr(const void *s, int c, size_t n)
{
unsigned char *mem;
unsigned char check;
mem = (unsigned char *)s;
check = (unsigned char)c;
while (n > 0)
{
if (*mem == check)
return (mem);
mem++;
n--;
}
return (0);
}
#include "libft.h"
int ft_memcmp(const void *s1, const void *s2, size_t n)
{
unsigned char *c1;
unsigned char *c2;
c1 = (unsigned char *)s1;
c2 = (unsigned char *)s2;
while (n > 0)
{
if (*c1 != *c2)
return (*c1 - *c2);
c1++;
c2++;
n--;
}
return (0);
}
#include "libft.h"
char *ft_strnstr(const char *haystack, const char *needle, size_t len)
{
size_t len2;
if (!*needle)
return ((char *)haystack);
len2 = ft_strlen(needle);
while (*haystack != 0 && len >= len2)
{
if (ft_strncmp(haystack, needle, len2) == 0)
return ((char *)haystack);
haystack++;
len--;
}
return (0);
}
// Main Example
int main()
{
char *p_src_str = "abcdefg";
char *p_find_str = "cde";
char *p_pos;
int n = 2;
p_pos = strnstr(p_src_str, p_find_str, n);
if (!p_pos)
return (0);
printf("기준 문자열 : %s\n", p_src_str);
printf("찾을 문자열 : %s\n", p_find_str);
printf("찾은 위치 : %s\n", p_pos);
}c
#include "libft.h"
static int is_space(char c)
{
if (c == ' ' || c == '\r' || c == '\f'
|| c == '\t' || c == '\v' || c == '\n')
return (1);
return (0);
}
int ft_atoi(const char *str)
{
size_t value;
size_t sign;
value = 0;
sign = 1;
while (is_space(*str))
str++;
if (*str == '-' || *str == '+')
{
if (*str == '-')
sign *= -1;
str++;
}
while (*str >= '0' && *str <= '9')
{
value = (value * 10) + (*str - '0');
str++;
}
return ((int)(value * sign));
}
#include "libft.h"
void *ft_calloc(size_t count, size_t size)
{
void *p;
p = (void *)malloc(count * size);
if (!p)
return (NULL);
ft_bzero(p, (count * size));
return (p);
}
#include "libft.h"
char *ft_strdup(const char *s)
{
char *p;
size_t i;
size_t len;
i = 0;
len = ft_strlen(s);
p = (char *)malloc(sizeof(char) * (len + 1));
if (!p)
return (NULL);
while (*(s + i) != '\0')
{
*(p + i) = *(s + i);
i++;
}
*(p + i) = '\0';
return (p);
}
#include "libft.h"
char *ft_substr(char const *s, unsigned int start, size_t len)
{
char *sub;
size_t i;
size_t slen;
if (!s)
return (NULL);
i = 0;
slen = ft_strlen(s);
if (start > slen || len == 0)
return (ft_strdup(""));
if (len > slen - start)
len = slen - start;
sub = (char *)malloc(sizeof(char) * (len + 1));
if (!sub)
return (NULL);
while (*(s + start + i) != '\0' && len > i)
{
*(sub + i) = *(s + start + i);
i++;
}
*(sub + i) = '\0';
return (sub);
}
// Main Example
#include <stdio.h>
int main(void)
{
char *str = "01234";
size_t size = 10;
char *ret = ft_substr(str, 10, size);
printf("%s\n", ret);
return (0);
}
#include "libft.h"
char *ft_strjoin(char const *s1, char const *s2)
{
char *p;
size_t len1;
size_t len2;
if (!s1 && !s2)
return (NULL);
else if (!s1)
return (ft_strdup(s2));
else if (!s2)
return (ft_strdup(s1));
len1 = ft_strlen(s1);
len2 = ft_strlen(s2);
p = (char *)malloc(sizeof(char) * (len1 + len2 + 1));
if (!p)
return (NULL);
ft_strlcpy(p, s1, len1 + 1);
ft_strlcat(p + len1, s2, len2 + 1);
return (p);
}
#include "libft.h"
char *ft_strtrim(char const *s, char const *set)
{
size_t i;
size_t len;
char *trim;
if (!s || !set)
return (NULL);
i = 0;
len = ft_strlen(s);
while (s[i] != '\0' && ft_strchr(set, s[i]))
i++;
while (s[len - 1] != '\0' && len > 0 && ft_strchr(set, s[len - 1]))
len--;
if (i > len)
return (ft_strdup(""));
trim = (char *)malloc(sizeof(char) * (len - i + 1));
if (!trim)
return (NULL);
ft_strlcpy(trim, &s[i], len - i + 1);
return (trim);
}
// Main Example
int main()
{
printf("%s\n", ft_strtrim("abqbc", "abc"));
printf("%s\n", ft_strtrim("xavocadoyz", "xyz"));
return 0;
}
#include "libft.h"
static char *ft_sub_split(const char *s, char c)
{
size_t i;
size_t len;
char *sub;
i = 0;
len = 0;
if (!s)
return (NULL);
while (*(s + len) != c && *(s + len))
len++;
sub = (char *)malloc(sizeof(char) * (len + 1));
if (!sub)
return (NULL);
while (len > i)
{
*(sub + i) = *(s + i);
i++;
}
*(sub + i) = '\0';
return (sub);
}
static char **ft_real_split(char const *s, char c, char **split, size_t count)
{
size_t i;
i = 0;
while (count > i)
{
while (*s == c && *s)
s++;
*(split + i) = ft_sub_split(s, c);
if (!*(split + i))
{
while (i--)
free(*(split + i));
free(split);
return (NULL);
}
i++;
while (*s != c && *s)
s++;
}
*(split + count) = NULL;
return (split);
}
char **ft_split(char const *s, char c)
{
size_t i;
size_t count;
char **split;
i = 0;
count = 0;
if (!s)
return (NULL);
while (*(s + i))
{
if (*(s + i) == c)
i++;
else
{
count++;
while (*(s + i) != c && *(s + i))
i++;
}
}
split = (char **)malloc(sizeof(char *) * (count + 1));
if (!split)
return (NULL);
split = ft_real_split(s, c, split, count);
return (split);
}
#include <stdio.h>
int main(void)
{
char *s;
char c;
char **words;
s = "asdf2439#85723RETV#WYWER5w%^YW#$%6";
c = '';
words = ft_split(s1, s2);
if (!*words) printf("(blank)\n");
while (*words)
printf("#1 - %s\n", *(words++));
printf("\n");
}
#include "libft.h"
static size_t ft_size(int n)
{
size_t size;
size = 0;
if (n < 0)
size++;
else if (n == 0)
size++;
while (n != 0)
{
n = n / 10;
size++;
}
return (size);
}
char *ft_itoa(int n)
{
size_t size;
char *str;
long long ln;
size = ft_size(n);
str = (char *)malloc(sizeof(char) * (size + 1));
if (!str)
return (NULL);
ln = (long long)n;
if (ln < 0)
{
str[0] = '-';
ln *= -1;
}
if (ln == 0)
str[0] = '0';
str[size--] = '\0';
while (ln != 0)
{
str[size--] = ln % 10 + '0';
ln /= 10;
}
return (str);
}
//Main Example
int main()
{
printf("%s\n", ft_itoa(0));
printf("%s\n", ft_itoa(987654321));
printf("%s\n", ft_itoa(-123456789));
}
#include "libft.h"
char *ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
size_t i;
size_t len;
char *str;
if (!s)
return (NULL);
i = 0;
len = ft_strlen(s);
str = (char *)malloc(sizeof(char) * (len + 1));
if (!str)
return (NULL);
while (len > i)
{
if (f != NULL)
str[i] = f(i, s[i]);
i++;
}
str[i] = '\0';
return (str);
}
// Main Example
#include <stdio.h>
char f(unsigned int i, char c)
{
char str;
str = c + 1;
return (str);
}
int main()
{
char str1[] = "abc";
char* str2;
str2 = ft_strmapi(str1, *f);
printf("%s\n", str2);
}
📖 참고 📖 함수 포인터
- 개념
- 함수의 주소를 저장하는 변수
- 상수 함수 포인터 : (*const 함수 포인터 이름)
- 할당 : int (*fp)() = 함수 이름;
- 호출 : (*fp)();
- 참고 사이트
#include "libft.h"
void ft_striteri(char *s, void (*f)(unsigned int, char *))
{
size_t i;
size_t len;
if (!s)
return ;
i = 0;
len = ft_strlen(s);
while (len > i)
{
if (f != NULL)
f(i, &s[i]);
i++;
}
}
#include "libft.h"
void ft_putchar_fd(char c, int fd)
{
write(fd, &c, 1);
}
📖 참고 📖 File Descriptor
- 개념
- 유닉스 시스템에서 프로세스 파일을 다루는 도구
- File Descriptor는 0이 아닌 양의 정수값(Non-negative Integer)을 가짐
- 프로세스가 실행 중에 파일을 open하면 사용하지 않은 숫자 중 가장 작은 값 할당
- 프로세스가 열려있는 파일에 시스템 콜을 이용하여 접근할 때, File Descriptor 이용해서 파일을 지칭 가능
- 기본적으로 할당되는 파일 디스크립터
- 0 : Standard Input
- 1 : Standart Output
- 2 : Standard Error
- 참고 사이트
#include "libft.h"
void ft_putstr_fd(char *s, int fd)
{
if (s != NULL)
{
while (*s != '\0')
{
write(fd, s, 1);
s++;
}
}
}
#include "libft.h"
void ft_putendl_fd(char *s, int fd)
{
if (s != NULL)
{
while (*s)
{
write(fd, s, 1);
s++;
}
write(fd, "\n", 1);
}
}
#include "libft.h"
void ft_putnbr_fd(int n, int fd)
{
long long nbr;
char c;
nbr = (long long)n;
if (nbr < 0)
{
write(fd, "-", 1);
nbr *= -1;
}
if (nbr >= 10)
ft_putnbr_fd(nbr / 10, fd);
c = nbr % 10 + '0';
write(fd, &c, 1);
}
NAME = libft.a
SRCS = ft_isalpha.c ft_isdigit.c ft_isalnum.c ft_isascii.c ft_isprint.c \
ft_strlen.c \
ft_memset.c ft_bzero.c ft_memcpy.c ft_memmove.c \
ft_strlcpy.c ft_strlcat.c \
ft_toupper.c ft_tolower.c \
ft_strchr.c ft_strrchr.c ft_strncmp.c \
ft_memchr.c ft_memcmp.c \
ft_strnstr.c \
ft_atoi.c ft_calloc.c \
ft_strdup.c ft_substr.c ft_strjoin.c ft_strtrim.c ft_split.c ft_itoa.c \
ft_strmapi.c ft_striteri.c \
ft_putchar_fd.c ft_putstr_fd.c ft_putendl_fd.c ft_putnbr_fd.c
OBJS = $(SRCS:.c=.o)
%.o : %.c libft.h
cc -Wall -Wextra -Werror -c $< -o $@
$(NAME) : $(OBJS)
ar rc $@ $(OBJS)
all : $(NAME)
clean :
rm -rf $(OBJS)
fclean : clean
rm -rf $(NAME)
re : fclean all
.PHONY : all clean fclean re
#ifndef LIBFT_H
# define LIBFT_H
# include <stdlib.h>
# include <unistd.h>
int ft_isalpha(int c);
int ft_isdigit(int c);
int ft_isalnum(int c);
int ft_isascii(int c);
int ft_isprint(int c);
void *ft_memset(void *b, int c, size_t n);
void ft_bzero(void *s, size_t n);
void *ft_memcpy(void *dst, const void *src, size_t n);
void *ft_memmove(void *dst, const void *src, size_t n);
size_t ft_strlen(const char *s);
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize);
size_t ft_strlcat(char *dst, const char *src, size_t dstsize);
int ft_toupper(int c);
int ft_tolower(int c);
char *ft_strchr(const char *s, int c);
char *ft_strrchr(const char *s, int c);
int ft_strncmp(const char *s1, const char *s2, size_t n);
void *ft_memchr(const void *s, int c, size_t n);
int ft_memcmp(const void *s1, const void *s2, size_t n);
char *ft_strnstr(const char *haystack, const char *needle, size_t len);
int ft_atoi(const char *str);
void *ft_calloc(size_t n, size_t size);
char *ft_strdup(const char *s);
char *ft_substr(const char *s, unsigned int start, size_t len);
char *ft_strjoin(const char *s1, const char *s2);
char *ft_strtrim(const char *s, const char *set);
char **ft_split(const char *s, char c);
char *ft_itoa(int n);
char *ft_strmapi(const char *s, char (*f)(unsigned int, char));
void ft_striteri(char *s, void (*f)(unsigned int, char*));
void ft_putchar_fd(char c, int fd);
void ft_putstr_fd(char *s, int fd);
void ft_putendl_fd(char *s, int fd);
void ft_putnbr_fd(int n, int fd);
#endif
📖 참고 📖 연결리스트
- 개념
- 배열과 달리 크기를 자유롭게 변경할 수 있는 자료구조
- 노드(리스트 내 각 요소)를 연결해서 만드는 리스트
- head : 리스트의 첫 번째 노드
- tail : 리스트의 마지막 노드
- 특징
- 장점 : 새로운 노드의 추가/삽입/삭제가 쉽고 빠름
- 단점 : 특정 위치에 있는 노드를 검색하는데 비용이 크고, 속도가 느림
- 참고 사이트
📖 참고 📖 malloc으로 메모리를 할당 이유
- malloc없이 새로운 노드를 만들게 되면, 해당 함수가 종료되면서 반환되는 new 노드는 stack에서 사라짐
- malloc을 하면 힙영역에 할당되고, 메모리 상에 남아 t_list *new 가 할당 받은 메모리를 가리킬 수 있음
- 메모리 구조
#include "libft.h"
t_list *ft_lstnew(void *content)
{
t_list *new;
new = (t_list *)malloc(sizeof(t_list));
if (!new)
return (NULL);
new->content = content;
new->next = NULL;
return (new);
}
#include <stdio.h>
int main(void)
{
t_list *head;
void *content;
head = NULL;
content = "abc";
head = ft_lstnew(content);
}
📖 참고 📖 연결 리스트 구현시 이중 포인터를 사용하는 이유
- 단일 연결리스트에서 삽입과 삭제를 통해 head 포인터의 값을 변화 가능
- 호출 함수의 포인터변수가 참조하는 객체를 피호출 함수에서 바꾸고자 할 경우 이중 포인터를 사용
- t_list **lst 변수가 담고있는 값은 t_list *의 주소 (= *lst는 head의 주소)
#include "libft.h"
void ft_lstadd_front(t_list **lst, t_list *new)
{
t_list *new_last;
if (lst != NULL && new != NULL)
{
new_last = ft_lstlast(new);
new_last->next = *lst;
*lst = new;
}
}
#include <stdio.h>
int main(void)
{
t_list *head;
t_list *front;
head = (t_list *)malloc(sizeof(t_list));
head->content = "a";
head->next = NULL;
}
#include "libft.h"
int ft_lstsize(t_list *lst)
{
size_t size;
size = 0;
while (lst != NULL)
{
lst = lst->next;
size++;
}
return (size);
}
#include "libft.h"
t_list *ft_lstlast(t_list *lst)
{
if (lst == NULL)
return (NULL);
while (lst->next != NULL)
lst = lst->next;
return (lst);
}
📖 참고 📖 *lst == NULL 과 lst == NULL 의 차이
- *lst == NULL : lst의 첫번째 주소 (헤드의 주소를 의미) 헤드가 비었다는 건, *lst는 빈 리스트 라는 의미
- lst == NULL : 리스트 자체가 존재하지 않는다는 의미
#include "libft.h"
void ft_lstadd_back(t_list **lst, t_list *new)
{
t_list *last;
if (lst != NULL && new != NULL)
{
if (*lst != NULL)
{
last = ft_lstlast(*lst);
last->next = new;
}
else
*lst = new;
}
}
📖 참고 📖 free(lst)만 하면 안되는 이유
- content 변수는 주소만 담고 있음
- 주소가 가리키는 값까지 삭제를 해줘야 하는데, free(lst)를 한 후에는 lst->content 로 접근이 불가능
- content를 먼저 free해주고 그 다음에 lst를 free 필요함
#include "libft.h"
void ft_lstdelone(t_list *lst, void (*del)(void *))
{
if (lst != NULL)
{
if (del != NULL)
del(lst->content);
free(lst);
}
}
#include "libft.h"
void ft_lstclear(t_list **lst, void (*del)(void *))
{
t_list *clear;
t_list *next;
clear = *lst;
while (clear != NULL)
{
next = clear->next;
if (del != NULL)
del(clear->content);
free(clear);
clear = next;
}
*lst = NULL;
}
#include "libft.h"
void ft_lstiter(t_list *lst, void (*f)(void *))
{
if (lst != NULL)
{
while (lst != NULL)
{
if (f != NULL)
f(lst->content);
lst = lst->next;
}
}
}
header file : <string.h>
function prototype
description
return value
#include "libft.h"
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *))
{
t_list *map;
t_list *tmp;
void *d;
if (!lst || !f)
return (NULL);
map = NULL;
while (lst != NULL)
{
d = f(lst->content);
tmp = ft_lstnew(d);
if (!tmp)
{
if (del != NULL)
del(d);
ft_lstclear(&map, del);
return (NULL);
}
ft_lstadd_back(&map, tmp);
lst = lst->next;
}
return (map);
}
NAME = libft.a
SRCS = ft_isalpha.c \
ft_isdigit.c \
ft_isalnum.c \
ft_isascii.c \
ft_isprint.c \
ft_strlen.c \
ft_memset.c \
ft_memcpy.c \
ft_memmove.c \
ft_strlcpy.c \
ft_strlcat.c \
ft_toupper.c \
ft_tolower.c \
ft_strchr.c \
ft_strrchr.c \
ft_strncmp.c \
ft_memchr.c \
ft_memcmp.c \
ft_strnstr.c \
ft_atoi.c \
ft_calloc.c \
ft_strdup.c \
ft_substr.c \
ft_strjoin.c \
ft_strtrim.c \
ft_split.c \
ft_itoa.c \
ft_strmapi.c \
ft_striteri.c \
ft_putchar_fd.c \
ft_putstr_fd.c \
ft_putendl_fd.c \
ft_putnbr_fd.c \
ft_bzero.c
SRCS_BN = ft_lstadd_front.c \
ft_lstsize.c \
ft_lstdelone.c \
ft_lstclear.c \
ft_lstiter.c \
ft_lstmap.c \
ft_lstnew.c \
ft_lstlast.c \
ft_lstadd_back.c
OBJS = $(SRCS:.c=.o)
OBJS_BONUS = $(SRCS_BN:.c=.o)
all : $(NAME)
$(NAME) : $(OBJS)
%.o : %.c libft.h
cc -Wall -Wextra -Werror -c $< -o $@
ar rc $(NAME) $@
clean :
rm -rf $(OBJS) $(OBJS_BONUS)
rm -rf bonus
fclean : clean
rm -rf $(NAME)
re : fclean all
bonus : $(OBJS) $(OBJS_BONUS)
.PHONY : all clean fclean re bonus
#ifndef LIBFT_H
# define LIBFT_H
# include <stdlib.h>
# include <unistd.h>
typedef struct s_list
{
void *content;
struct s_list *next;
}t_list;
int ft_isalpha(int c);
int ft_isdigit(int c);
int ft_isalnum(int c);
int ft_isascii(int c);
int ft_isprint(int c);
void *ft_memset(void *b, int c, size_t len);
void ft_bzero(void *s, size_t n);
void *ft_memcpy(void *dst, const void *src, size_t n);
void *ft_memmove(void *dst, const void *src, size_t len);
size_t ft_strlen(const char *s);
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize);
size_t ft_strlcat(char *dst, const char *src, size_t dstsize);
int ft_toupper(int c);
int ft_tolower(int c);
char *ft_strchr(const char *s, int c);
char *ft_strrchr(const char *s, int c);
int ft_strncmp(const char *s1, const char *s2, size_t n);
void *ft_memchr(const void *s, int c, size_t n);
int ft_memcmp(const void *s1, const void *s2, size_t n);
char *ft_strnstr(const char *haystack, const char *needle, size_t len);
int ft_atoi(const char *str);
void *ft_calloc(size_t count, size_t size);
char *ft_strdup(const char *s);
char *ft_substr(char const *s, unsigned int start, size_t len);
char *ft_strjoin(char const *s1, char const *s2);
char *ft_strtrim(char const *s, char const *set);
char **ft_split(char const *s, char c);
char *ft_itoa(int n);
char *ft_strmapi(char const *s, char (*f)(unsigned int, char));
void ft_striteri(char *s, void (*f)(unsigned int, char*));
void ft_putchar_fd(char c, int fd);
void ft_putstr_fd(char *s, int fd);
void ft_putendl_fd(char *s, int fd);
void ft_putnbr_fd(int n, int fd);
t_list *ft_lstnew(void *content);
void ft_lstadd_front(t_list **lst, t_list *new);
int ft_lstsize(t_list *lst);
t_list *ft_lstlast(t_list *lst);
void ft_lstadd_back(t_list **lst, t_list *new);
void ft_lstdelone(t_list *lst, void (*del)(void *));
void ft_lstclear(t_list **lst, void (*del)(void *));
void ft_lstiter(t_list *lst, void (*f)(void *));
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void*));
#endif