这是我第一次问一个问题,所以我可能做错了什么,我为此道歉。
所以,我在C中做了一个函数来动态分配一个二维数组void**,这样我就可以强制转换它,并使用这个函数来创建一个二维数组char或int,或者如果需要的话。函数如下:
void **ft_new_arr(size_t row, size_t col, size_t size)
{
void **arr_ptr;
int *arr_byte;
size_t total_size;
size_t y;
if (row == 0 || col == 0 || size == 0)
return (NULL);
total_size = (col * sizeof(void*)) + (row * col * size);
if ((total_size - col * sizeof(void*)) != (row * col * size))
return (NULL);
arr_ptr = (void**)malloc(total_size);
if (arr_ptr == NULL)
return (NULL);
memset(arr_ptr, 0, total_size);
arr_byte = (int *)arr_ptr + col * sizeof(void*);
y = 0;
while (y < col)
{
arr_ptr[y] = arr_byte + (y * (row * size));
y++;
}
return (arr_ptr);
}
我知道的唯一问题是,我可能会浪费一些内存,因为所有的行都将具有相同的大小,但我想这并不是那么糟糕。
为了测试它,我做了一个函数,将一个字符串(char *)拆分为空格(ASCII中为0到32),并在之前分配的数组中的每一列填入该字符串的一个单词,然后我做了一个函数来打印我的数组。
这是我的分裂函数:
static int get_nb_words(char *str)
{
int i;
int res;
i = 0;
res = 0;
while (str[i])
{
while (str[i] && str[i] >= 0 && str[i] <= 32)
i++;
if (str[i] && str[i] > 32)
{
while (str[i] && str[i] > 32)
i++;
res++;
}
}
return (res);
}
static int get_word_len(char *str)
{
int i;
int tmp;
int res;
i = 0;
tmp = 0;
res = 0;
while (str[i])
{
while (str[i] && str[i] >= 0 && str[i] <= 32)
i++;
if (str[i] && str[i] > 32)
{
tmp = 0;
while (str[i] && str[i] > 32)
{
i++;
tmp++;
}
if (tmp > res)
res = tmp;
}
}
return (res);
}
static void fill_array(char **new_arr, char *str)
{
int i;
int x;
int y;
i = 0;
x = 0;
y = 0;
while (str[i])
{
while (str[i] && str[i] >= 0 && str[i] <= 32)
i++;
if (str[i] && str[i] > 32)
{
y = 0;
while (str[i] && str[i] > 32)
{
new_arr[x][y] = str[i];
i++;
y++;
}
new_arr[x][y] = '\0';
x++;
}
}
}
void ft_printab(char **new_arr, int nb_row)
{
for (int i = 0; i < nb_row; i++)
printf("arr[%d] = |%s|\n", i, new_arr[i]);
}
char **ft_split(char *str)
{
int nb_words;
int words_len;
char **new_arr;
nb_words = 0;
words_len = 0;
if (!str)
return (NULL);
nb_words = get_nb_words(str);
words_len = get_word_len(str);
if (!nb_words || !words_len)
return (NULL);
new_arr = (char **)ft_new_arr(words_len, nb_words, sizeof(char));
if (!new_arr)
return (NULL);
fill_array(new_arr, str);
ft_printab(new_arr, nb_words);
return (new_arr);
}
下面是主要的btw:
int main(int ac, char **av)
{
if (ac != 2)
return (print_err("Invalid number of arguments", -1));
char **new_arr;
new_arr = ft_split(av[1]);
free(new_arr);
return (0);
}
我必须说,如果我不填充或打印数组,我不会得到错误。
当我这样做的时候,数组就像我希望的那样被填充了,但是valgrind给了我很多错误:
==401691== Memcheck, a memory error detector
==401691== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==401691== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==401691== Command: ./cub3d I\ am\ a\ Fish
==401691==
==401691== Invalid write of size 1
==401691== at 0x109830: fill_array (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10999F: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== Address 0x4a9f0c0 is 16 bytes inside an unallocated block of size 4,194,096 in arena "client"
==401691==
==401691== Invalid write of size 1
==401691== at 0x109881: fill_array (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10999F: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== Address 0x4a9f0c1 is 17 bytes inside an unallocated block of size 4,194,096 in arena "client"
==401691==
==401691== Conditional jump or move depends on uninitialised value(s)
==401691== at 0x484ED19: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==401691== by 0x48EADB0: __vfprintf_internal (vfprintf-internal.c:1517)
==401691== by 0x48D481E: printf (printf.c:33)
==401691== by 0x1098EF: ft_printab (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x1099B0: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691==
==401691== Conditional jump or move depends on uninitialised value(s)
==401691== at 0x484ED28: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==401691== by 0x48EADB0: __vfprintf_internal (vfprintf-internal.c:1517)
==401691== by 0x48D481E: printf (printf.c:33)
==401691== by 0x1098EF: ft_printab (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x1099B0: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691==
==401691== Conditional jump or move depends on uninitialised value(s)
==401691== at 0x48FF7B7: _IO_new_file_xsputn (fileops.c:1218)
==401691== by 0x48FF7B7: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1196)
==401691== by 0x48EB08B: outstring_func (vfprintf-internal.c:239)
==401691== by 0x48EB08B: __vfprintf_internal (vfprintf-internal.c:1517)
==401691== by 0x48D481E: printf (printf.c:33)
==401691== by 0x1098EF: ft_printab (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x1099B0: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691==
==401691== Syscall param write(buf) points to uninitialised byte(s)
==401691== at 0x4988A37: write (write.c:26)
==401691== by 0x48FEF6C: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1180)
==401691== by 0x4900A60: new_do_write (fileops.c:448)
==401691== by 0x4900A60: _IO_new_do_write (fileops.c:425)
==401691== by 0x4900A60: _IO_do_write@@GLIBC_2.2.5 (fileops.c:422)
==401691== by 0x48FF754: _IO_new_file_xsputn (fileops.c:1243)
==401691== by 0x48FF754: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1196)
==401691== by 0x48EA049: outstring_func (vfprintf-internal.c:239)
==401691== by 0x48EA049: __vfprintf_internal (vfprintf-internal.c:1593)
==401691== by 0x48D481E: printf (printf.c:33)
==401691== by 0x1098EF: ft_printab (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x1099B0: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== Address 0x4a9f0ba is 10 bytes inside a block of size 1,024 alloc'd
==401691== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==401691== by 0x48F2C23: _IO_file_doallocate (filedoalloc.c:101)
==401691== by 0x4901D5F: _IO_doallocbuf (genops.c:347)
==401691== by 0x4900FDF: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:744)
==401691== by 0x48FF754: _IO_new_file_xsputn (fileops.c:1243)
==401691== by 0x48FF754: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1196)
==401691== by 0x48E91CC: outstring_func (vfprintf-internal.c:239)
==401691== by 0x48E91CC: __vfprintf_internal (vfprintf-internal.c:1263)
==401691== by 0x48D481E: printf (printf.c:33)
==401691== by 0x1098EF: ft_printab (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x1099B0: ft_split (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691== by 0x10922A: main (in /mnt/nfs/homes/hlevi/42/Ghub/Cub3D/cub3d)
==401691==
arr[0] = |I|
arr[1] = |am|
arr[2] = |a|
arr[3] = |Fish|
==401691==
==401691== HEAP SUMMARY:
==401691== in use at exit: 0 bytes in 0 blocks
==401691== total heap usage: 2 allocs, 2 frees, 1,072 bytes allocated
==401691==
==401691== All heap blocks were freed -- no leaks are possible
==401691==
==401691== Use --track-origins=yes to see where uninitialised values come from
==401691== For lists of detected and suppressed errors, rerun with: -s
==401691== ERROR SUMMARY: 36 errors from 6 contexts (suppressed: 0 from 0)
我一定是哪里出了问题,但是我已经试了很多方法,仍然不能成功,有人有什么解决办法吗?
1条答案
按热度按时间3wabscal1#
好的,谢谢你的回答,我做错的是声明
int *arr_byte
而不是int8_t*
或char*
。感谢伊恩,衬垫是错的!
现在,该函数运行良好