I'm just starting on the road the learning C, and ran into some difficulty:
我刚刚开始学习C语言,并遇到了一些困难:
The code listed below is giving me the following error:
下面列出的代码给出了以下错误:
Attaching to program: `/workfolder/cocoa/c_stuff/bookshelf/build/Debug/bookshelf', process 1674.
Cannot access memory at address 0xa0df194
Cannot access memory at address 0xa0df194
附加到程序:`/ workfolder / cocoa / c_stuff / bookshelf / build / Debug / bookshelf',进程1674.无法访问地址0xa0df194的内存无法访问地址0xa0df194的内存
// code start
#define MAX_NAME_LENGTH 200
#define MAX_AUTHOR_LENGTH 200
#define MAX_DESCRIPTION_LENGTH 1000
#define MAX_PUBLISHER 200
#define MAX_ISBN 50
//structures<
typedef struct {
char title[MAX_NAME_LENGTH];
char author[MAX_AUTHOR_LENGTH];
char ISBN[MAX_ISBN];
char description[MAX_DESCRIPTION_LENGTH];
char publisher[MAX_PUBLISHER];
} Book;
void getUserInput(Book *s[])
{
printf("what is the book's title ?\n");
fgets(s[book_count]->title, MAX_NAME_LENGTH, stdin);
printf("what is the author's name?\n");
fgets(s[book_count]->author, MAX_AUTHOR_LENGTH, stdin);
printf("what is the ISBN?\n");
fgets(s[book_count]->ISBN, MAX_ISBN, stdin);
printf("write a short description\n");
fgets(s[book_count]->description, MAX_DESCRIPTION_LENGTH, stdin);
printf("what is the book's publisher\n");
fgets(s[book_count]->publisher, MAX_PUBLISHER, stdin);
printf("want to add another book ? Y\\N\n");
book_count++;
if(tolower(fgetc(stdin)) == 'y')
{
return getUserInput(s);
}
else
{
return;
}
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
if((book_shelf[0] = (Book *)malloc(sizeof(Book))) == NULL)
{
exit(1);
}
getUserInput(book_shelf);
return 0;
}
The code compiles properly, and the function runs fine the first time (all the questions get asked and the struct receives the data); but when the user types 'y' to add another book, the mem error occurs.
代码编译正确,第一次运行正常(所有问题都被询问,结构接收数据);但是当用户键入“y”以添加另一本书时,会发生mem错误。
Any ideas where the error is happening?
任何错误发生的想法?
Thanks in advance!
提前致谢!
9 个解决方案
#1
You've only ever allocated memory for the first book in main - after that it tries to write to the next slot in the array, which doesn't point to an allocated block of memory, giving you a seg-fault. You're going to have to allocate memory for each book you want to read in.
你只为main中的第一本书分配了内存 - 之后它试图写入数组中的下一个插槽,它不指向已分配的内存块,给你一个seg-fault。您将不得不为要阅读的每本书分配内存。
In addition, since C doesn't know how long an array is, you have to pass that information along into function calls. (And I don't see where you're defining book_count.)
另外,由于C不知道数组有多长,因此必须将该信息传递给函数调用。 (而且我没有看到你在哪里定义book_count。)
You might try something along these lines:
您可以尝试以下这些方面:
void getUserInput(Book *s[], int *book_count, int max_book_count)
{
if (book_count == max_book_count) return; // If we've filled all the slots, we can't add anymore without causing trouble.
s[book_count] = malloc(sizeof(Book));
..
if(tolower(fgetc(stdin)) == 'y')
{
(*book_count)++;
getUserInput(s, book_count, max_book_count);
}
return;
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
int book_count = 0;
getUserInput(book_shelf, &book_count, 100);
// Make sure to free all the malloc'd data
}
Even better in this situation, would just be using a loop and skipping the whole recursion step.
在这种情况下更好的是,只使用循环并跳过整个递归步骤。
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
char response = 'y';
int book_count = 0;
while (book_count < 100 && response == 'y')
{
book_shelf = malloc(sizeof(Book));
response = getUserInput(book_shelf[book_count++]);
}
// make sure to free all the allocated data!
}
char getUserInput(Book *book)
{
// write input straight to book
printf("what is the book's title ?\n");
fgets(book->title, MAX_NAME_LENGTH, stdin);
...
return tolower(fgetc(stdin));
}
#2
Unless I'm reading something wrong, you haven't defined book_count before using it as an array subscript.
除非我读错了,否则在将它用作数组下标之前,你还没有定义book_count。
#3
Within main, you allocated on the stack an array of 100 pointers to the Book Structure. I believe it was your intent to allocate 100 structures and then pass the address to that block of structures to getUserInput
在main中,您在堆栈上分配了一个包含指向Book Structure的100个指针的数组。我相信你打算分配100个结构,然后将地址传递给getUserInput结构块
Change main to:
将主要更改为:
Book book_shelf[100];
...
getUserInput(book_shelf);
...
EDIT: OOPS Missed the single Book malloc mentioned in the earlier post. That ones Correct for the first book. If you edit as above and eliminate the if (book_shelf[0]...) check, you'll accomplish your intended results
编辑:OOPS错过了前一篇文章中提到的单一书籍malloc。那些正确的第一本书。如果您按上述方式进行编辑并取消if(book_shelf [0] ...)检查,您将完成预期的结果
#4
-
You allocate just space for the firstbook, not for the others (malloc in main)
你只为第一本书分配空间,而不是为其他人分配空间(主要的malloc)
-
I guess there is some code missing, no declaration and initialization of book_count
我想有一些代码缺失,没有book_count的声明和初始化
-
You should use loops instead of recursion
您应该使用循环而不是递归
-
Use not recursion but loops for this kind of repetition
不使用递归,而是循环这种重复
#5
Recursion is probably overkill for this problem where a simple do { ... } while(user keeps answering yes) would do. However the problem you having is in main with your Book *book_shelf[100]. There are several ways you could solve this problem.
对于这个简单的do {...} while(用户一直回答是)的问题,递归可能有点过头了。但是你遇到的问题主要在于你的Book * book_shelf [100]。有几种方法可以解决这个问题。
First change it to an array of Book's like samills suggests:
首先将它更改为一系列书籍,就像萨米尔斯一样:
Book book_shelf[100];
and then change your getUserInput to something like this:
然后将getUserInput更改为以下内容:
getUserInput(Book *book_shelf, int offset, int length) {
if(offset < 0 || offset >= length) {
return;
}
//...
return getUserInput(book_shelf, offset + 1, length)
}
Or you could use your existing code and change you getUserInput function to look something like this and remove the malloc from main:
或者您可以使用现有代码并将getUserInput函数更改为如下所示并从main中删除malloc:
getUserInput(Book *book_shelf) {
book_shelf[book_count] = (Book*)malloc(sizeof(Book));
// ...
}
props for correct use of the sizeof operator (I see that thing misused so often it makes my eyes bleed).
正确使用sizeof操作符的道具(我看到那个经常误用的东西让我的眼睛流血)。
#6
As in Josh's answer, by adding the following lines to your code should make it work:
正如Josh的回答一样,通过在代码中添加以下行应该使其工作:
book_count++; if(tolower(fgetc(stdin)) == 'y') { if((book_shelf[book_count] = (Book *)malloc(sizeof(Book))) == NULL) { printf("Cannot allocate memory for Book"); exit(1); } return getUserInput(s); } else { return; }
However, I encourage you not to use the recursive function for getting input. Recursive can lead to difficulties in debugging. You may consider using normal loop instead.
但是,我建议您不要使用递归函数来获取输入。递归可能导致调试困难。您可以考虑使用普通循环。
Note: I'm assuming the book_count is global variable which has been initialized to 0
注意:我假设book_count是全局变量,已初始化为0
#7
thanks a lot for the replies!
非常感谢回复!
I realized that I hadn't malloc-ed enough memory to handle more then one element of the struct array (Exactly what Josh is saying). So essentially:
我意识到我没有malloc-ed足够的内存来处理结构数组的多个元素(正是Josh所说的)。基本上:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码
so the second time around I would hit a memory issue.
所以第二次我会遇到内存问题。
thanks again!
#8
Looks like your still doing it wrong:
看起来你仍然做错了:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码
book_shelf is only the size of a pointer. When you do the malloc you only allocate one Book at a time. This is wrong. You need to allocate contiguous memory for an array of Book objects all in one instanciation of an array.
book_shelf只是指针的大小。当您执行malloc时,您一次只能分配一本Book。这是错的。您需要在一个数组的实例中为一个Book对象数组分配连续的内存。
Like
Book book_shelf[100];
not
Book *book_shelf[100];
or using malloc, use your pointer to point to an array instanciated using
100*malloc(sizeof(Book)).
或者使用malloc,使用指针指向使用100 * malloc(sizeof(Book))实例化的数组。
You may get lucky that no other heap memory is allocated in between your malloc(sizeof(Book)) calls and that the memory management system is alocating contiguous memory by default. Also, book_shelf will only point to the last malloced Book structure, not the first one as you indicated you want in your original question.
您可能会幸运的是,在您的malloc(sizeof(Book))调用之间没有分配其他堆内存,并且内存管理系统默认情况下正在分配连续内存。此外,book_shelf将仅指向最后一个malloced Book结构,而不是您在原始问题中指示的第一个结构。
Josh is also not allocating enough memory at one time. Use a linked list if you want to keep extending elements to the end of your book_shelf one-by-one.
Josh也没有同时分配足够的内存。如果要逐个将元素扩展到book_shelf的末尾,请使用链接列表。
#9
factorial with pointer and recursion
带指针和递归的阶乘
#include<iostream.h>
#include<conio.h>
int show(int *p)
{
int f;
int x=*p;
if(*p==1) //boundry checking for recursion
return 1;
else
f=x*show(&(--*p)); //this code is similar to f=x*show(n-1); with non-pointers
return f;
}
void main()
{
int a=6;
int b=show(&a);
cout<<b;
getch();
}
#1
You've only ever allocated memory for the first book in main - after that it tries to write to the next slot in the array, which doesn't point to an allocated block of memory, giving you a seg-fault. You're going to have to allocate memory for each book you want to read in.
你只为main中的第一本书分配了内存 - 之后它试图写入数组中的下一个插槽,它不指向已分配的内存块,给你一个seg-fault。您将不得不为要阅读的每本书分配内存。
In addition, since C doesn't know how long an array is, you have to pass that information along into function calls. (And I don't see where you're defining book_count.)
另外,由于C不知道数组有多长,因此必须将该信息传递给函数调用。 (而且我没有看到你在哪里定义book_count。)
You might try something along these lines:
您可以尝试以下这些方面:
void getUserInput(Book *s[], int *book_count, int max_book_count)
{
if (book_count == max_book_count) return; // If we've filled all the slots, we can't add anymore without causing trouble.
s[book_count] = malloc(sizeof(Book));
..
if(tolower(fgetc(stdin)) == 'y')
{
(*book_count)++;
getUserInput(s, book_count, max_book_count);
}
return;
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
int book_count = 0;
getUserInput(book_shelf, &book_count, 100);
// Make sure to free all the malloc'd data
}
Even better in this situation, would just be using a loop and skipping the whole recursion step.
在这种情况下更好的是,只使用循环并跳过整个递归步骤。
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
char response = 'y';
int book_count = 0;
while (book_count < 100 && response == 'y')
{
book_shelf = malloc(sizeof(Book));
response = getUserInput(book_shelf[book_count++]);
}
// make sure to free all the allocated data!
}
char getUserInput(Book *book)
{
// write input straight to book
printf("what is the book's title ?\n");
fgets(book->title, MAX_NAME_LENGTH, stdin);
...
return tolower(fgetc(stdin));
}
#2
Unless I'm reading something wrong, you haven't defined book_count before using it as an array subscript.
除非我读错了,否则在将它用作数组下标之前,你还没有定义book_count。
#3
Within main, you allocated on the stack an array of 100 pointers to the Book Structure. I believe it was your intent to allocate 100 structures and then pass the address to that block of structures to getUserInput
在main中,您在堆栈上分配了一个包含指向Book Structure的100个指针的数组。我相信你打算分配100个结构,然后将地址传递给getUserInput结构块
Change main to:
将主要更改为:
Book book_shelf[100];
...
getUserInput(book_shelf);
...
EDIT: OOPS Missed the single Book malloc mentioned in the earlier post. That ones Correct for the first book. If you edit as above and eliminate the if (book_shelf[0]...) check, you'll accomplish your intended results
编辑:OOPS错过了前一篇文章中提到的单一书籍malloc。那些正确的第一本书。如果您按上述方式进行编辑并取消if(book_shelf [0] ...)检查,您将完成预期的结果
#4
-
You allocate just space for the firstbook, not for the others (malloc in main)
你只为第一本书分配空间,而不是为其他人分配空间(主要的malloc)
-
I guess there is some code missing, no declaration and initialization of book_count
我想有一些代码缺失,没有book_count的声明和初始化
-
You should use loops instead of recursion
您应该使用循环而不是递归
-
Use not recursion but loops for this kind of repetition
不使用递归,而是循环这种重复
#5
Recursion is probably overkill for this problem where a simple do { ... } while(user keeps answering yes) would do. However the problem you having is in main with your Book *book_shelf[100]. There are several ways you could solve this problem.
对于这个简单的do {...} while(用户一直回答是)的问题,递归可能有点过头了。但是你遇到的问题主要在于你的Book * book_shelf [100]。有几种方法可以解决这个问题。
First change it to an array of Book's like samills suggests:
首先将它更改为一系列书籍,就像萨米尔斯一样:
Book book_shelf[100];
and then change your getUserInput to something like this:
然后将getUserInput更改为以下内容:
getUserInput(Book *book_shelf, int offset, int length) {
if(offset < 0 || offset >= length) {
return;
}
//...
return getUserInput(book_shelf, offset + 1, length)
}
Or you could use your existing code and change you getUserInput function to look something like this and remove the malloc from main:
或者您可以使用现有代码并将getUserInput函数更改为如下所示并从main中删除malloc:
getUserInput(Book *book_shelf) {
book_shelf[book_count] = (Book*)malloc(sizeof(Book));
// ...
}
props for correct use of the sizeof operator (I see that thing misused so often it makes my eyes bleed).
正确使用sizeof操作符的道具(我看到那个经常误用的东西让我的眼睛流血)。
#6
As in Josh's answer, by adding the following lines to your code should make it work:
正如Josh的回答一样,通过在代码中添加以下行应该使其工作:
book_count++; if(tolower(fgetc(stdin)) == 'y') { if((book_shelf[book_count] = (Book *)malloc(sizeof(Book))) == NULL) { printf("Cannot allocate memory for Book"); exit(1); } return getUserInput(s); } else { return; }
However, I encourage you not to use the recursive function for getting input. Recursive can lead to difficulties in debugging. You may consider using normal loop instead.
但是,我建议您不要使用递归函数来获取输入。递归可能导致调试困难。您可以考虑使用普通循环。
Note: I'm assuming the book_count is global variable which has been initialized to 0
注意:我假设book_count是全局变量,已初始化为0
#7
thanks a lot for the replies!
非常感谢回复!
I realized that I hadn't malloc-ed enough memory to handle more then one element of the struct array (Exactly what Josh is saying). So essentially:
我意识到我没有malloc-ed足够的内存来处理结构数组的多个元素(正是Josh所说的)。基本上:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码
so the second time around I would hit a memory issue.
所以第二次我会遇到内存问题。
thanks again!
#8
Looks like your still doing it wrong:
看起来你仍然做错了:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码
book_shelf is only the size of a pointer. When you do the malloc you only allocate one Book at a time. This is wrong. You need to allocate contiguous memory for an array of Book objects all in one instanciation of an array.
book_shelf只是指针的大小。当您执行malloc时,您一次只能分配一本Book。这是错的。您需要在一个数组的实例中为一个Book对象数组分配连续的内存。
Like
Book book_shelf[100];
not
Book *book_shelf[100];
or using malloc, use your pointer to point to an array instanciated using
100*malloc(sizeof(Book)).
或者使用malloc,使用指针指向使用100 * malloc(sizeof(Book))实例化的数组。
You may get lucky that no other heap memory is allocated in between your malloc(sizeof(Book)) calls and that the memory management system is alocating contiguous memory by default. Also, book_shelf will only point to the last malloced Book structure, not the first one as you indicated you want in your original question.
您可能会幸运的是,在您的malloc(sizeof(Book))调用之间没有分配其他堆内存,并且内存管理系统默认情况下正在分配连续内存。此外,book_shelf将仅指向最后一个malloced Book结构,而不是您在原始问题中指示的第一个结构。
Josh is also not allocating enough memory at one time. Use a linked list if you want to keep extending elements to the end of your book_shelf one-by-one.
Josh也没有同时分配足够的内存。如果要逐个将元素扩展到book_shelf的末尾,请使用链接列表。
#9
factorial with pointer and recursion
带指针和递归的阶乘
#include<iostream.h>
#include<conio.h>
int show(int *p)
{
int f;
int x=*p;
if(*p==1) //boundry checking for recursion
return 1;
else
f=x*show(&(--*p)); //this code is similar to f=x*show(n-1); with non-pointers
return f;
}
void main()
{
int a=6;
int b=show(&a);
cout<<b;
getch();
}