- 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/
我正在尝试向 iOS 应用商店提交更新。我要从 Buzztouch 应用程序转到 Sprite Kit 应用程序。我能够存档 Xcode 项目并提交它。该应用程序的状态为“上传已收到”,但大约一分钟后
我收到了这个奇怪的警告。我不确定是什么原因造成的。 .dia文件扩展名应该表示核心有向图图形文件。我没有添加,应用程序几乎没有用户界面。 最佳答案 我对这个答案并不满意,但我认为它可以帮助人们,直到找
下面用作 Uri 参数的程序集限定字符串在 XAML 中工作,但在代码中使用时会出现错误。 我尝试了各种 UriKind,结果都相同。我该如何解决这个问题? [Test] public void La
我正在开发一个 Angular 应用程序,目的是将其部署到移动设备和 Web 浏览器上。设置表单样式以显示无效输入时,我应该定位 Angular“ng-invalid”类还是 HTML5“:inval
我有一个在 Google App Engine 上运行的应用程序,它是 Android 应用程序的后端。它基本上是 Android 应用程序和在我自己的服务器上运行的 MySQL 数据库之间的桥梁。
我的代码是这样的: func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle,
I need to encrypt using Python with the A256GCM algorithm, and getting back a JWT that I need to
无法成功编译webpack并生成bundle.js文件。据我了解,我的 src_dir 和 dist_dir 变量能够指向正确的路径,但在尝试编译时我仍然始终收到两个错误之一。 配置对象无效。 Web
因此,当我在 postgres 上运行 regexp_matches 时收到一条错误消息,并且无法弄清楚如何通过它。它似乎在 regex101 等 reg_exp 测试站点上运行良好,但不幸的是在实际
这些是我正在使用的导入: import com.novell.ldap.*; import java.io.UnsupportedEncodingException; 我正在尝试进行一个非常简单的密码
在记录器函数的简写情况下,Pylint 提示 Invalid constant name "myprint"(invalid-name)。 # import from utils import get
我试图创建一个HTML输入标签,该标签仅接受以2种格式之一输入的数字,并拒绝所有其他输入。 我只想接受以下格式的数字,包括破折号: 1234-12 和 1234-12-12 注意:不是日期,而是合法的
我一直在尝试使用 Bootstrap 的表单样式处理 AngularJS 的电子邮件验证,并遇到了这个 CSS block 。 input:focus:required:invalid, textar
我正在编写一个程序,以确保我了解如何在 C 中正确实现单向链表。我目前正在哈佛的 CS50 类(class)中学习,并且使用本教程,因为 CS50 人员不解释链接详细列出数据结构:https://ww
此问题与询问同一消息的另一个问题不重复,但在另一个上下文中。这个问题的上下文只是关于上传截图图像和获取消息。 今天,我在将图片上传到 App Store Connect 时收到一条新消息: Inval
我的代码似乎运行良好,但当我滑动以删除 UITableView 中的一行时,应用程序崩溃并显示以下内容: 错误 LittleToDoApp[70390:4116002] *** Terminating
当我尝试发送语音消息时,总是收到无效的url错误。我正在使用Whisper将音频转换为文本,但由于某种原因,我似乎无法将文件传递给Whisper。当我在Java脚本中使用它而不是在TypeScrip中
我正在尝试在 flutter 上对 http 客户端进行单元测试。在模拟 http 和我的存储库类之后: void main() { MockHttpCLient mockHttpCLient;
我正在使用 pandoc 作为一个库,相关的代码片段是: module Lib ( latexDirToTex, latexToTxt ) where import qualified
我正在开发一个(相对简单的)Rails应用程序。我正在使用Devise gem处理用户 session 。每当我导航到localhost:3000/users/sign_in时,我都会看到Devise
我是一名优秀的程序员,十分优秀!