我刚刚开始学习C语,并遇到了一些困难:
下面列出的代码给出了以下错误:
附加到程序:`/ 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;
}
代码编译正确,第一次运行正常(所有问题都被提出,结构接收数据);但是当用户键入“y”以添加另一本书时,会发生mem错误。
发生错误的任何想法?
提前致谢!
答案 0 :(得分:10)
你只为main中的第一本书分配了内存 - 之后它试图写入数组中的下一个插槽,它没有指向已分配的内存块,给你一个seg-fault。您将不得不为要阅读的每本书分配内存。
此外,由于C不知道数组的长度,因此必须将该信息传递给函数调用。 (我不知道你在哪里定义book_count。)
你可以尝试这些方法:
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
}
在这种情况下更好,只是使用循环并跳过整个递归步骤。
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));
}
答案 1 :(得分:2)
除非我读错了,否则在将它用作数组下标之前,你还没有定义book_count。
答案 2 :(得分:2)
在main中,您在堆栈上分配了一个包含指向Book Structure的100个指针的数组。我相信你打算分配100个结构,然后将地址传递给结构块以获取getUserInput
将main更改为:
Book book_shelf[100];
...
getUserInput(book_shelf);
...
编辑:OOPS错过了前一篇文章中提到的单一书籍malloc。那些正确的第一本书。如果你编辑如上并消除 如果(book_shelf [0] ...)检查,您将完成预期的结果
答案 3 :(得分:1)
您只为第一本书分配空间,而不为其他人分配空间(主要的malloc)
我猜有些代码缺失,没有声明和初始化book_count
您应该使用循环而不是递归
使用not recursion但循环进行此类重复
答案 4 :(得分:1)
对于这个问题来说,递归可能有点过头了,其中一个简单的do {...} while(用户一直回答是)会这样做。但是你遇到的问题主要在于你的Book * book_shelf [100]。有几种方法可以解决这个问题。
首先将它更改为像's sillills这样的Book数组:
Book book_shelf[100];
然后将你的getUserInput更改为:
getUserInput(Book *book_shelf, int offset, int length) {
if(offset < 0 || offset >= length) {
return;
}
//...
return getUserInput(book_shelf, offset + 1, length)
}
或者您可以使用现有代码并将getUserInput函数更改为如下所示并从main中删除malloc:
getUserInput(Book *book_shelf) {
book_shelf[book_count] = (Book*)malloc(sizeof(Book));
// ...
}
正确使用sizeof操作符的道具(我看到那个经常被滥用的东西让我眼睛流血)。
答案 5 :(得分:0)
正如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; }
但是,我建议您不要使用递归函数来获取输入。递归可能导致调试困难。您可以考虑使用普通循环。
注意:我假设book_count是全局变量,已初始化为0
答案 6 :(得分:0)
非常感谢你的回复!
我意识到我没有malloc-ed足够的内存来处理结构数组的一个元素(正是Josh所说的)。基本上是这样的:
Book * book_shelf;
if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码
所以第二次我会遇到内存问题。
再次感谢!
答案 7 :(得分:0)
看起来你仍然做错了:
Book * book_shelf;
if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码
book_shelf只是指针的大小。当您执行malloc时,您一次只能分配一本Book。这是错的。您需要在一个数组的实例中为一个Book对象数组分配连续的内存。
喜欢
Book book_shelf [100];
不
Book * book_shelf [100];
或使用malloc,使用指针指向使用
实例化的数组
100 * malloc的(的sizeof(书))。
您可能很幸运,在您的malloc(sizeof(Book))调用之间没有分配其他堆内存,并且默认情况下内存管理系统正在分配连续内存。此外,book_shelf将仅指向最后一个malloced Book结构,而不是您在原始问题中指示的第一个结构。
Josh也没有一次分配足够的内存。如果您希望将元素一个接一个地扩展到book_shelf的末尾,请使用链接列表。
答案 8 :(得分:0)
带指针和递归的阶乘
#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();
}