- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我意识到这个问题在这里已经被打死了,但我完全不知道为什么这个错误仍然发生在我身上。
请记住,这不是作业或任何东西,因此您在我的实现中看到的任何逻辑缺陷/错误都是由于缺乏编程经验造成的;我没有,这是我第一次尝试实现典型的数据结构。我目前正在尝试自学编程,所以请理解我是否在任何地方犯了任何明显的错误。
就是说,这里是二叉搜索树实现的源代码(还有一些我扔进去的其他垃圾东西;我试着让 cin 像 C++ 的 cin 一样):
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <limits.h>
#include <stdint.h>
#define INIT_BUF_SIZE 1
#define INIT_STACK_SIZE 1
#define ERROR_MSG "The program could not allocate enough memory :[\n"
typedef enum {false, true} bool;
typedef struct Node {
int value;
int quantity;
struct Node *parent;
struct Node *left;
struct Node *right;
} Node;
typedef struct Node_Stack {
unsigned int size;
unsigned int max_size;
Node **s;
} Node_Stack;
typedef struct Count_Stack {
unsigned int size;
unsigned int max_size;
unsigned int *s;
} Count_Stack;
Node *root = NULL;
Node_Stack stack;
Count_Stack c_stack;
/********************* Stack Operations *********************/
bool init_c_stack (void) {
unsigned int *temp = calloc(INIT_STACK_SIZE, sizeof(int));
if (temp == NULL) {return false;}
c_stack.s = temp;
c_stack.size = 0;
c_stack.max_size = INIT_STACK_SIZE;
return true;
}
void delete_c_stack (void) {
c_stack.s = NULL;
c_stack.size = 0;
c_stack.max_size = 0;
free(c_stack.s);
}
bool init_stack (void) {
Node **temp = calloc(INIT_STACK_SIZE, sizeof(Node *));
if (temp == NULL) {return false;}
stack.s = temp;
stack.size = 0;
stack.max_size = INIT_STACK_SIZE;
return true;
}
void delete_stack (void) {
stack.s = NULL;
stack.size = 0;
stack.max_size = 0;
free(stack.s);
}
bool init_stacks (void) {return init_stack() && init_c_stack();}
void delete_stacks (void) {
delete_c_stack();
delete_stack();
}
bool update_c_stack (void) {
if (c_stack.s == NULL) {return false;}
unsigned int *t = realloc(c_stack.s,
sizeof(*c_stack.s)*(c_stack.max_size + 1));
if (t == NULL) {return false;}
c_stack.s = t;
c_stack.max_size++;
return true;
}
bool update_stack (void) {
if (stack.s == NULL) {return false;}
Node **t = realloc(stack.s, sizeof(*stack.s)*(stack.max_size + 1));
if (t == NULL) {return false;}
printf("stack.max_size before = %u\n", stack.max_size);
printf("reallocated to %d bytes\n",
sizeof(Node *)*(stack.max_size + 1));
stack.s = t;
stack.max_size++;
printf("stack.max_size after = %u\n", stack.max_size);
return true;
}
bool push_count (unsigned int i) {
if (c_stack.s == NULL) {return false;}
if (c_stack.size < c_stack.max_size || update_c_stack()) {
c_stack.s[c_stack.size++] = i;
return true;
}
return false;
}
bool push (Node *i) {
if (stack.s == NULL) {return false;}
if (stack.size < stack.max_size || update_stack()) {
stack.s[stack.size++] = i;
return true;
}
return false;
}
/******************* End of Stack Operations *******************/
bool add_node (int x) {
if (get_num_levels(root) == UINT_MAX) {
printf("Failed to add %d to tree\n", x);
return false;
}
Node *f = find(root, x), *t = (Node *)calloc(1, sizeof(Node)), *p;
if (root == NULL) {
t->value = x;
t->quantity = 1;
t->parent = NULL;
t->left = NULL;
t->right = NULL;
root = t;
}
else if (f == NULL) { // x doesn't exist in tree
f = root;
p = f->parent;
while (f != NULL) {
p = f;
if (x < f->value) {f = f->left;}
else if (x > f->value) {f = f->right;}
}
t->value = x;
t->quantity = 1;
t->parent = p;
t->left = NULL;
t->right = NULL;
if (x < p->value) {p->left = t;}
else if (x > p->value) {p->right = t;}
else {f->quantity++;} // x already exists in tree
}
printf("\n" TREE_SEPERATOR "\n");
printf("\nAdded node containing %d\n", x);
print_tree_formatted();
printf("\nNow %d nodes in the tree.\n", get_num_nodes(root));
printf("\nNow %d levels in the tree.\n", get_num_levels(root));
return true;
}
bool remove_node (int x) {
Node *f = find(root, x);
if (f != NULL) {
if (f->quantity > 1) {f->quantity--;}
else {replace_node(f); free(f);}
printf("\n" TREE_SEPERATOR "\n");
printf("\nRemoved node containing %d\n", x);
print_tree_formatted();
printf("\nNow %d nodes in the tree.\n", get_num_nodes(root));
printf("\nNow %d levels in the tree.\n", get_num_levels(root));
return true;
}
return false;
}
/*************************************************************************
* Function Name: *
* str_split *
* Purpose: *
* The function below takes a single string and breaks it up into a *
* set of constituent sub-strings, based on the delimiter that is *
* passed in to break the string by. *
* Parameters: *
* - s The string to be split *
* - len The length of the string *
* - c The size of the returned char * array *
* - delim The delimiter by which the string s is to be broken up by *
* Return Value: *
* char ** A pointer to an array of c number of strings, or NULL on *
* failure to allocate enough space *
*************************************************************************/
char **str_split (char *s, unsigned int len, unsigned int c, const char delim) {
char **result;
unsigned int i, j, k = 0, l;
if (s == NULL || len == 0) {return NULL;}
/* Allocate memory for c number of strings/char pointers */
result = calloc(c + 1, sizeof(char *));
if (result != NULL) {
for (i = 0; i < c + 1; i++) {
/* Allocate space for the actual chars for each string */
result[i] = calloc(len, sizeof(char));
if (result[i] == NULL) {return NULL;}
}
/***************************************************************
* i holds index of advancing pointer *
* j holds index of following pointer *
* k holds index of string in returning array of char pointers *
* l holds index of char in string *
***************************************************************
* Loop over and copy contents of s into the each index of *
* result *
***************************************************************/
for (i = 0, j = 0; i < len; i++) {
l = 0;
if (s[i] == delim) {
for (; j < i; j++) {result[k][l++] = s[j];}
k++;
j = i + 1;
}
}
for (; j < i; j++) {result[k][l++] = s[j];}
}
return result;
}
/*************************************************************************
* Function Name: *
* cin *
* Purpose: *
* The function below allows for "continuous" user input, based on *
* how much the user has already entered, by dynamically allocating *
* more memory whenever the input buffer is maxed out. *
* Parameters: *
* - cur_size The initial allocation size for the input buffer *
* Return Value: *
* char * A string/pointer to an array of characters or NULL *
* if allocation failed *
*************************************************************************/
char *cin (unsigned int cur_size) {
char *input = (char *)malloc(cur_size);
int i = 0, c = EOF;
if (input != NULL) {
// cook keyboard input until NL or EOF
while ((c = getchar()) != '\n' && c != EOF) {
if ((char)c == 8 || (char)c == 127) {
printf("\b \b\b \b\b \b");
fflush(stdout);
i = (i > 0) ? i - 1 : i;
}
else {
input[i++] = (char)c;
if (i == cur_size) {
/* Attempt to double the current size of the buffer */
cur_size *= 2;
input = realloc(input, cur_size);
if (input == NULL) {
printf("Unable to allocate enough memory for input\n");
break;
}
}
}
}
// null-terminate user input
input[i] = '\0';
}
return input;
}
...
int main (void) {
char *input, **s, t, delim = ' ';
unsigned int len, i, count, result;
bool valid;
/* Allocate space for both stacks */
init_stacks(); // DO NOT MOVE OR DUPLICATE CALL
while (true) {
/* Continuously grab null-terminated user input string */
input = cin(INIT_BUF_SIZE);
if (input != NULL) {
len = string_length(input);
/* Get the number of times the char delim appears in input */
count = num_in_string(input, delim);
/***********************************************************
* First word in user input should either be: *
* - "add" *
* - "remove" *
* - "print" *
* - Any of the exit commands ("q", "quit", or "exit"). *
***********************************************************/
t = input[0];
/* Exit loop if first token is an exit command */
if (user_exit(input)) {break;}
/*******************************************************
* Only process user input if there's at least 2 words *
* Eg: add 1 <-- Valid *
* add <-- Invalid *
* remove 1 <-- Valid *
* foobar <-- Invalid *
*******************************************************/
if (count > 0) {
/* Get the user input split up by spaces */
s = str_split(input, len, ++count, delim);
if (s != NULL) {
/*******************************************
* Look at each token entered by the user, *
* except the first one *
*******************************************/
for (i = 1; i < count; i++) {
/***********************************************
* Assuming the token is a number, convert the *
* token to an integer *
***********************************************/
result = string_to_int(s[i], &valid);
if (same_string(s[0], "print")) {
if (same_string(s[1], "stack")) {
printf("size = %u\n", stack.size);
printf("max_size = %u\n", stack.max_size);
}
else {printf("%s\n", s[i]);}
fflush(stdout);
}
else if (valid) {
if (same_string(s[0], "add")) {
add_node(result);
}
else if (same_string(s[0], "remove")) {
remove_node(result);
}
}
}
/* Free up memory allocated for split user input */
for (i = 0; i < count; i++) {free(s[i]);} // DO NOT MOVE
free(s); // DO NOT MOVE
}
else {printf(ERROR_MSG);} // couldn't allocate heap space
}
/* Free up memory allocated for cin */
free(input); // DO NOT MOVE
}
}
/* Free up memory allocated for both stacks */
delete_stacks(); // DO NOT MOVE
return 0;
}
因此,当我运行它时,程序运行良好,因为我添加了以下树(按顺序): 15, 7, 23, 3, 11, 19, 27 .
然后,当我将数字 5 添加到树中时,程序因名义错误而崩溃。我试过使用 gdb
(和 lldb)进行调试,但我认为这不是很有效,即使打开了 -g 标志也是如此。
这对我来说没有意义,因为 update_stack
和 update_count_stack
中对 realloc
的调用不会失败 prior 添加数字 5。
我也确实意识到将动态分配的内存块的大小一遍又一遍地增加 1 不是典型的或好的做法,因为它效率低下,但我只是想知道为什么 这发生在这里,以及我如何能够修复它 - 我觉得我只是遗漏了一些明显的东西,并且正在为一些小事拉扯我的头发!
感谢大家的反馈。
我昨天不小心把我的源文件复制粘贴到这里,所以请原谅我现在必须运行。从那以后,我尝试尽量减少发布的代码以仅显示相关函数,其中包括调用 malloc
、realloc
或 free
的函数。我还尝试在代码中添加一些注释以帮助更好地理解它。
最佳答案
回答其中一个 OP 问题;
增加分配时,
在每次增量时,增量 I.E. 的数量加倍。 1, 2, 4, 9 ...
记录当前可用的最大值和实际使用的电流,
只有在没有可用空间时才调用 `realloc()
关于c - 重新分配(): getting an invalid pointer error in C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41603292/
我知道使用 GET 和 SET 函数的公共(public)变量的缺点/私有(private)变量的优点,但目前我正在使用 Ogre3D 开发自己的第一个“真实”游戏(C++)..同时,我有时需要 6-
我正在开发一个 GSM/GPRS 应用程序,它将每 10 秒报告一些值。我必须使用的 SIM 卡每月只有 15MB 可用数据。我使用的是 SIM900 GSM 芯片供您引用。 我到达服务器的方式是通过
这三者有什么区别:gets - 它获取带有 '\n' 的行gets.chomp - 它得到一行,但删除 '\n' 这样对吗? gets.chomp! 怎么样? 最佳答案 gets - 它得到一个末尾带
问题和我现在遇到的问题 脚本 顺便说一句,评论是挪威语的,如果它们看起来很奇怪哈哈 Connect-AzureAD #variabel $Users = Get-AzureADUser -All:$t
我现在面临的问题是获取一个 URL,如下所示: www.example.com/example.php?url=www.google.com 现在的问题是,如果我的网址中有一个 get,如下所示: w
我有一个 queryString 传递给 servlet 的 doGet() 方法,如下所示: count=9&preId0=-99&objId0=-99&preId1=-99&objId1=-99&
这是我在 Django 模板中的代码: {% for tag in tags %} {{ tag }} {% endfor %} 在view.py中: def tag_find(
我正在尝试在express.js中为我的网络应用程序创建一个路由系统,我需要知道是否需要使用app.get/post/put/delete.apply以编程方式设置多个功能对于一条路线。 也是如此 a
我正在通过示例查看 A.Mele Django,第 1 章 def post_list(request, category=None): object_list = Post.publishe
如果我想找到与IIS站点或应用程序关联的目录,我该怎么做? 我似乎无法从Get-Website和Get-WebApplication的对象的任何属性中找到任何允许我这样做的东西。 最佳答案 只需查看一
不知道发生了什么。当我执行以下代码时......它运行良好......但它产生了错误。如果我将以下内容粘贴到我的浏览器地址栏中并点击它,我会得到一个 URL。如果我通过 KRL http:get 输入
Curl 提供了一系列不同的带有 X 前缀的 http 方法调用,但也提供了不带 X 的相同方法。我两种都试过了,但我似乎无法弄清楚其中的区别。有人可以快速向我解释这两种操作有何不同吗? 最佳答案 默
request.GET.get 是什么意思?我在 Django 中看到类似的东西 page = request.GET.get('page', 1) 我认为它与类似的东西有关 « 它们是如
我正在从我的 Angular2 站点查询一些 Elasticsearch 服务器。为了帮助提高安全性,我们希望锁定对 GET 请求的访问权限。 Elasticsearch 支持带主体的 GET,但我在
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 4年前关闭。 Improve t
调用 HTable.get(List) 返回的 Result 数组的顺序是什么? ? 我的意思是,假设与输入列表的顺序相同是否正确? 最佳答案 结果数组中的顺序将与输入列表的顺序相同。与批处理方法一样
所以我有一个看起来像这样的 JSON 数组: var myData = { foo : { biz : 'baz', fig : 'tree' } }
我正在学习 Ajax、javascript 和 html,并且有一个应用程序可以触发“get”请求,然后再触发另一个“get”请求。这些请求是用户按下按钮的结果。在我的 servlet 中,我使用 T
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
运行以下 cmdlet 适用于组成员(Amer 域中的组)中的所有用户,无论列出的用户位于哪个域: Get-ADGroupMember -Server amer 但是,当尝试通过管道传输到 Get-
我是一名优秀的程序员,十分优秀!