为什么我的结构成员之一在尝试在函数中更改后未定义?我传递了结构作为参考
我正在为 search_tree() 函数编写代码,该函数用目录及其子目录中的所有文件填充 chArray 结构(动态字符数组)。
但是,我在使用 add_elements() 函数时遇到问题,该函数旨在将元素添加到 char 数组并相应地调整其大小。
尽管我将 chArray 变量作为函数的引用传递,但 array.size 成员在函数调用后未定义。
为什么会发生这种情况?
- 除此之外,我遇到了内存分配错误,但我几乎可以肯定其原因是 array.size 未定义的问题。
谢谢您的帮助!
PS 我已经在下面包含了我的整个代码,对于所有随机打印语句和奇怪的名称感到抱歉 - 这是我试图找出问题所在。
//
// Created by mario on 05/03/2022.
//
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <stddef.h>
#ifndef errno
extern int errno;
#endif
typedef struct {
int init;
int numEls;
size_t size;
char **elements;
} chArray;
void initArray(chArray *arr, int n, ...) {
size_t c_size = 0;
va_list ptr;
arr = malloc(sizeof(chArray));
*arr = (chArray) {.init = 1, .numEls = n, .size = sizeof(chArray), .elements = NULL};
va_start(ptr, n);
for (int i = 0; i < n; i++) {
char *arg = va_arg(ptr, char*);
c_size += strlen(arg) + 1;
printf("%lu\n", c_size);
if (i == 0) {
arr->elements = (char **) malloc(strlen(arg) + 1);
}
else {
arr->elements = realloc(arr->elements, arr->size + strlen(arg) + 1);
}
*(arr->elements + i) = arg;
}
va_end(ptr);
arr->size = c_size + offsetof(chArray, elements);
printf("%lu\n", arr->size);
}
void add_elements(chArray *arr, int n, ...) {
va_list ptr;
size_t new_size = arr->size;
va_start(ptr, n);
for (int i = 0; i < n; i++) {
char *f_arg = va_arg(ptr, char *);
new_size += strlen(f_arg) + 1;
}
va_end(ptr);
arr = realloc(arr, new_size);
va_start(ptr, n);
for (int i = arr->numEls; i < n+arr->numEls; i++) {
char *arg = va_arg(ptr, char*);
arr->size += strlen(arg) + 1;
if (i == 0) {
arr->elements = (char **) malloc(strlen(arg) + 1);
}
else {
arr->elements = realloc(arr->elements, arr->size + strlen(arg) + 1);
}
*(arr->elements + i) = arg;
}
va_end(ptr);
arr->numEls += n;
}
int search_tree(char *tree, char *contains, chArray *ends) {
struct dirent *entry;
DIR *dir;
struct stat buff;
mode_t mode;
char *not1 = ".";
char *not2 = "..";
unsigned long int tree_length = strlen(tree);
char *last = tree + tree_length - 1;
#ifdef _WIN32
if (last != '\\') {
char *slash = "\\\0";
#else
if (*last != '/') {
char *slash = "/\0";
#endif
if (*last == '\\') {
char *temp = (char *) malloc(tree_length + 1);
memset(temp, '\0', tree_length + 1);
strncpy(temp, tree, tree_length - 1);
tree = 0;
tree = (char *) malloc(tree_length + 2);
strcpy(tree, temp);
strcat(tree, slash);
free(temp);
}
else {
char *temp = (char *) malloc(tree_length + 2);
memset(temp, '\0', tree_length + 2);
strcpy(temp, tree);
tree = 0;
tree = (char *) malloc(tree_length + 2);
strcpy(tree, temp);
strcat(tree, slash);
free(temp);
}
}
if (ends->init != 1) {
printf("Once\n");
initArray(ends, 0);
}
if ((dir = opendir(tree)) == NULL) {
perror("An error occurred");
fprintf(stderr, "Errno = %d", errno);
return -1;
}
while ((entry = readdir(dir)) != NULL) {
size_t length = strlen(tree) + strlen(entry->d_name) + 1;
char *file_path = (char *) malloc(length);
memset(file_path, '\0', length);
strcpy(file_path, tree);
strcat(file_path, entry->d_name);
if (stat(file_path, &buff) != -1) {
mode = buff.st_mode;
if (S_ISDIR(mode) && (strcmp(entry->d_name, not1) != 0) && (strcmp(entry->d_name, not2) != 0)) {
search_tree(file_path, contains, ends);
for (int i = 0; i < ends->numEls; i++) {
printf("%s\n", *(ends->elements));
}
} else if (S_ISREG(mode)) {
if (contains == NULL) {
add_elements(ends, 1, file_path);
for (int i = 0; i < ends->numEls; i++) {
printf("%s\n", *(ends->elements));
}
}
else {
if (strstr(file_path, contains) != NULL) {
add_elements(ends, 1, file_path);
for (int i = 0; i < ends->numEls; i++) {
printf("%s\n", *(ends->elements));
}
}
}
}
}
else {
perror("An error occurred");
fprintf(stderr, "Errno = %d", errno);
return -1;
}
}
closedir(dir);
return 0;
}
int main(int argc, char *argv[]) {
char *path = "/Users/mario/python";
char *toComp = "python";
// printf("%d\n", strcmp(strstr(path, "python"), toComp));
chArray test;
initArray(&test, 3, "Hello", "There", "Goodbye");
printf("%lu\n", test.size);
add_elements(&test, 10, "Soyez", "Jiduan", "Chifa3n", "Chifa4n", "Chifa5n", "Chif6an", "Chifan7", "Chifa8n", "Chifan9", "Chifan10");
for (int i = 0; i < 6; i++) {
printf("%s\n", *(test.elements + i));
}
chArray ends;
char *tree = "/Users/mario/Desktop";
search_tree(tree, ".py", &ends);
printf("%lu\n", sizeof(ends));
printf("%s\n%s\n", *ends.elements, *(ends.elements + 1));
chArray *random = (chArray * ) malloc(48);
printf("%lu\n", sizeof(*random));
return 0;
}
输出:
36
4486016032
search_tree(4025,0x117c5a600)malloc:***对象0x7ff7b48d0838的错误:未分配正在重新分配的指针 search_tree(4025,0x117c5a600) malloc: *** 在 malloc_error_break 中设置断点进行调试
36 是从 add_elements() 函数中打印的数组大小,第二个数字相同,但在函数之后打印。
到底是怎么回事?
I am writing code for a search_tree() function which fills a chArray struct (dynamic char array) with all the files in a directory and its sub-directories.
However, I'm having problems with the add_elements() function, which is meant to add elements to the char array and adjust its size accordingly.
The array.size member is undefined after the function call, even though I passed the chArray variable as reference to the function.
Why is this happening?
-Apart from this I'm having memory allocation errors, but I'm nearly sure the reason for this is this issue with array.size being undefined.
Thank you for any help!!
P.S. I've included my entire code below, sorry for all the random print statements and weird names - this was me trying to figure out what was wrong.
//
// Created by mario on 05/03/2022.
//
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <stddef.h>
#ifndef errno
extern int errno;
#endif
typedef struct {
int init;
int numEls;
size_t size;
char **elements;
} chArray;
void initArray(chArray *arr, int n, ...) {
size_t c_size = 0;
va_list ptr;
arr = malloc(sizeof(chArray));
*arr = (chArray) {.init = 1, .numEls = n, .size = sizeof(chArray), .elements = NULL};
va_start(ptr, n);
for (int i = 0; i < n; i++) {
char *arg = va_arg(ptr, char*);
c_size += strlen(arg) + 1;
printf("%lu\n", c_size);
if (i == 0) {
arr->elements = (char **) malloc(strlen(arg) + 1);
}
else {
arr->elements = realloc(arr->elements, arr->size + strlen(arg) + 1);
}
*(arr->elements + i) = arg;
}
va_end(ptr);
arr->size = c_size + offsetof(chArray, elements);
printf("%lu\n", arr->size);
}
void add_elements(chArray *arr, int n, ...) {
va_list ptr;
size_t new_size = arr->size;
va_start(ptr, n);
for (int i = 0; i < n; i++) {
char *f_arg = va_arg(ptr, char *);
new_size += strlen(f_arg) + 1;
}
va_end(ptr);
arr = realloc(arr, new_size);
va_start(ptr, n);
for (int i = arr->numEls; i < n+arr->numEls; i++) {
char *arg = va_arg(ptr, char*);
arr->size += strlen(arg) + 1;
if (i == 0) {
arr->elements = (char **) malloc(strlen(arg) + 1);
}
else {
arr->elements = realloc(arr->elements, arr->size + strlen(arg) + 1);
}
*(arr->elements + i) = arg;
}
va_end(ptr);
arr->numEls += n;
}
int search_tree(char *tree, char *contains, chArray *ends) {
struct dirent *entry;
DIR *dir;
struct stat buff;
mode_t mode;
char *not1 = ".";
char *not2 = "..";
unsigned long int tree_length = strlen(tree);
char *last = tree + tree_length - 1;
#ifdef _WIN32
if (last != '\\') {
char *slash = "\\\0";
#else
if (*last != '/') {
char *slash = "/\0";
#endif
if (*last == '\\') {
char *temp = (char *) malloc(tree_length + 1);
memset(temp, '\0', tree_length + 1);
strncpy(temp, tree, tree_length - 1);
tree = 0;
tree = (char *) malloc(tree_length + 2);
strcpy(tree, temp);
strcat(tree, slash);
free(temp);
}
else {
char *temp = (char *) malloc(tree_length + 2);
memset(temp, '\0', tree_length + 2);
strcpy(temp, tree);
tree = 0;
tree = (char *) malloc(tree_length + 2);
strcpy(tree, temp);
strcat(tree, slash);
free(temp);
}
}
if (ends->init != 1) {
printf("Once\n");
initArray(ends, 0);
}
if ((dir = opendir(tree)) == NULL) {
perror("An error occurred");
fprintf(stderr, "Errno = %d", errno);
return -1;
}
while ((entry = readdir(dir)) != NULL) {
size_t length = strlen(tree) + strlen(entry->d_name) + 1;
char *file_path = (char *) malloc(length);
memset(file_path, '\0', length);
strcpy(file_path, tree);
strcat(file_path, entry->d_name);
if (stat(file_path, &buff) != -1) {
mode = buff.st_mode;
if (S_ISDIR(mode) && (strcmp(entry->d_name, not1) != 0) && (strcmp(entry->d_name, not2) != 0)) {
search_tree(file_path, contains, ends);
for (int i = 0; i < ends->numEls; i++) {
printf("%s\n", *(ends->elements));
}
} else if (S_ISREG(mode)) {
if (contains == NULL) {
add_elements(ends, 1, file_path);
for (int i = 0; i < ends->numEls; i++) {
printf("%s\n", *(ends->elements));
}
}
else {
if (strstr(file_path, contains) != NULL) {
add_elements(ends, 1, file_path);
for (int i = 0; i < ends->numEls; i++) {
printf("%s\n", *(ends->elements));
}
}
}
}
}
else {
perror("An error occurred");
fprintf(stderr, "Errno = %d", errno);
return -1;
}
}
closedir(dir);
return 0;
}
int main(int argc, char *argv[]) {
char *path = "/Users/mario/python";
char *toComp = "python";
// printf("%d\n", strcmp(strstr(path, "python"), toComp));
chArray test;
initArray(&test, 3, "Hello", "There", "Goodbye");
printf("%lu\n", test.size);
add_elements(&test, 10, "Soyez", "Jiduan", "Chifa3n", "Chifa4n", "Chifa5n", "Chif6an", "Chifan7", "Chifa8n", "Chifan9", "Chifan10");
for (int i = 0; i < 6; i++) {
printf("%s\n", *(test.elements + i));
}
chArray ends;
char *tree = "/Users/mario/Desktop";
search_tree(tree, ".py", &ends);
printf("%lu\n", sizeof(ends));
printf("%s\n%s\n", *ends.elements, *(ends.elements + 1));
chArray *random = (chArray * ) malloc(48);
printf("%lu\n", sizeof(*random));
return 0;
}
Output:
36
4486016032
search_tree(4025,0x117c5a600) malloc: *** error for object 0x7ff7b48d0838: pointer being realloc'd was not allocated
search_tree(4025,0x117c5a600) malloc: *** set a breakpoint in malloc_error_break to debug
The 36 is the array's size printed from within the add_elements() function, and the second number is the same but printed just after the function.
What is going on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论