指针逻辑导致内存访问冲突 [英] Pointer logic causing a memory access violation
问题描述
我已经使用指针读取文本文件并使用指针操作向文件中添加新记录,但我无法通过指针看到我在这个方法中出错了。我设置了指针to next和prev指向列表,但是当我调用它时,它是空的。
这是方法:
I have used pointers to read a text file and add a new record to the file using pointer manipulation,but I can''t see where I''m going wrong in this method with the pointers.I have set the pointers to next and prev to point to the list but when I call it,it''s empty.
This is the method:
struct contact *readFile(char * FName,struct contact *ptrList)
{
struct contact *head, *newContact;
FILE *fptr;
char oneLine[60];
char *sname, *fname, *phone,*company, *email;
head = ptrList;
fptr = fopen(FName,"r");
if(fptr == NULL)
{
printf("\nCant open file!");
return(ptrList);
}
fgets(oneLine, 55, fptr);
while(!feof(fptr))
{
fgets(oneLine, 55, fptr);
if(oneLine[strlen(oneLine)-1] == '\n')
{
oneLine[strlen(oneLine)-1] = '\0';
}
sname = strtok(oneLine,",");
fname = strtok(NULL,",");
phone = strtok(NULL,",");
company = strtok(NULL,",");
email = strtok(NULL,",");
if(head == NULL)
{
head = (struct contact *)malloc(sizeof(struct contact));
ptrList = head;
strcpy(head->sname,sname);
strcpy(head->fname,fname);
strcpy(head->phone,phone);
strcpy(head->company,company);
strcpy(head->email, email);
head->prev = NULL;
head->next = NULL;
}
else
{
newContact = (struct contact *)malloc(sizeof(struct contact));
head->next = newContact;
newContact->prev = head;
newContact->next = ptrList;
//copy the data to the new one
strcpy(head->sname,sname);
strcpy(head->fname,fname);
strcpy(head->phone,phone);
strcpy(head->company,company);
strcpy(head->email,email);
//move down the list so that the head variable
//points to the last contact
head = newContact;
}
}//end while
fclose(fptr);
return(ptrList);
}
struct contact definition:
struct contact definition:
struct contact {
char sname[15];
char fname[15];
char phone[15];
char company[15];
char email[15];
struct contact *prev;
struct contact *next;
};
任何关于为什么的想法列表没有填充?
Any ideas as to why the list is not populating?
推荐答案
啊,毕竟不是那么难。我猜你复制并粘贴了这段代码
Ah, not so hard after all. I guess you copied and pasted this code
strcpy(head->sname,sname);
strcpy(head->fname,fname);
strcpy(head->phone,phone);
strcpy(head->company,company);
strcpy(head->email, email);
从如果
到 else
阻止不改变头
到 newContact
所以它只是一次又一次地覆盖头部项目?
from the if
to the else
block without changing head
to newContact
so it just overwrites the head item again and again?
有很多错误:
1.函数调用应该是:
struct contact * readFile(char * FName,struct contact ** ptrList)//指向指针的指针如果ptrList为NULLPTR,则
返回失败。 if * ptrList是一个有效的指针,找到尾随元素并设置为它。即:for(head = * ptrList; head&& head-> next; head = head-> next);
2. head应始终是尾随元素。因此,如果* ptrList是NULLPTR,则应将其加入* ptrList。 if(!* ptrList)* ptrList = head;
3.最后:
There are many mistakes:
1. function call should be:
struct contact *readFile(char * FName,struct contact** ptrList) // pointer to pointer
return fail if ptrList is NULLPTR. if *ptrList is a valid pointer find the trailing element and set head to it. i.e: for(head=*ptrList;head&&head->next;head=head->next);
2. head should be always the trailing element. So you should join it to the *ptrList if *ptrList is a NULLPTR. if(!*ptrList) *ptrList=head;
3. finally:
<br />
struct contact *readFile(char * FName,struct contact** ptrList)<br />
{<br />
// open file and other stuff<br />
if(!ptrList) return; // invalid pointer<br />
for(head=*ptrList;head&&head->next;head=head->next);<br />
while( ReadLine(fptr,oneLine) )<br />
{<br />
sname = strtok(oneLine,",");<br />
fname = strtok(NULL,",");<br />
phone = strtok(NULL,",");<br />
company = strtok(NULL,",");<br />
email = strtok(NULL,",");<br />
<br />
newContact = (struct contact *)malloc(sizeof(struct contact));<br />
if(!newContact) break; // out of memory<br />
newContact->prev = head;<br />
newContact->next = 0;<br />
<br />
//copy the data to the new one<br />
strcpy(newContact->sname,sname);<br />
strcpy(newContact->fname,fname);<br />
strcpy(newContact->phone,phone);<br />
strcpy(newContact->company,company);<br />
strcpy(newContact->email,email);<br />
<br />
head = newContact;<br />
if(!*ptrList) *ptrList = head; // see: point 2<br />
}<br />
}<br />
edit 2012-04-24:我将附加一个新的改进解决方案。请阅读评论专栏!
edit 2012-04-24: i will append a new improved solution. please read the comment lines!
<span class="code-preprocessor">#pragma</span> once
<span class="code-preprocessor">#include</span> <stdio.h>
<span class="code-preprocessor">#include</span> <string.h>
<span class="code-preprocessor">#include</span> <stdlib.h>
<span class="code-keyword">typedef</span> <span class="code-keyword">unsigned</span> <span class="code-keyword">int</span> HRESULT;
<span class="code-preprocessor">#define</span> NULLPTR 0
<span class="code-comment">// node struct</span>
<span class="code-keyword">struct</span> contact
{
<span class="code-keyword">char</span> sname[15];
<span class="code-keyword">char</span> fname[15];
<span class="code-keyword">char</span> phone[15];
<span class="code-keyword">char</span> company[15];
<span class="code-keyword">char</span> email[15];
<span class="code-keyword">struct</span> contact* prev;
<span class="code-keyword">struct</span> contact* next;
};
<span class="code-comment">// error values</span>
<span class="code-keyword">enum</span>
{
S_OK = 0,
E_FAIL = -1,
E_POINTER = -2,
};
<span class="code-comment">//////////////////////////////////////////////</span>
<span class="code-comment">// prototypes</span>
<span class="code-comment">// callback function type</span>
<span class="code-keyword">typedef</span> <span class="code-keyword">void</span> (*FNWALK)(<span class="code-keyword">struct</span> contact* node);
<span class="code-keyword">void</span> DeletePtrList(<span class="code-keyword">struct</span> contact* ptrList);
HRESULT ReadFile(<span class="code-keyword">const</span> <span class="code-keyword">char</span>* FName,<span class="code-keyword">struct</span> contact** ptrList);
<span class="code-keyword">void</span> WalkChain(<span class="code-keyword">struct</span> contact* ptrList,FNWALK fnwalk);
<span class="code-comment">//////////////////////////////////////////////</span>
<span class="code-comment">// debug trace function</span>
<span class="code-keyword">void</span> trace_node(<span class="code-keyword">struct</span> contact* node)
{
<span class="code-keyword">if</span>(node)
{
printf(<span class="code-string">"--- node ---\n"</span>);
printf(<span class="code-string">"sname : %s\n"</span>,node->sname );
printf(<span class="code-string">"fname : %s\n"</span>,node->fname );
printf(<span class="code-string">"phone : %s\n"</span>,node->phone );
printf(<span class="code-string">"company: %s\n"</span>,node->company);
printf(<span class="code-string">"email : %s\n"</span>,node->email );
}
}
<span class="code-comment">// program entry point</span>
<span class="code-keyword">int</span> main(<span class="code-keyword">int</span> argc, <span class="code-keyword">char</span>* argv[])
{
<span class="code-comment">// command line: exe [file1] [file2] ...</span>
<span class="code-keyword">if</span>(1<argc)
{
<span class="code-keyword">struct</span> contact* ptrList = 0;
<span class="code-comment">// try to load the file into a chained list of nodes</span>
<span class="code-keyword">if</span>(S_OK==ReadFile(argv[1],&ptrList))
{
printf(<span class="code-string">"file loaded: %s\n"</span>,argv[1]);
<span class="code-comment">// at this point you can load another file to chain it</span>
<span class="code-keyword">if</span>(2<argc)
{
<span class="code-comment">// ptrList is valid. all new nodes will be chained to the trail</span>
<span class="code-keyword">if</span>(S_OK==ReadFile(argv[2],&ptrList))
{
printf(<span class="code-string">"file loaded: %s\n"</span>,argv[2]);
}
}
<span class="code-comment">// show all nodes loaded</span>
WalkChain(ptrList,trace_node);
<span class="code-comment">// free the memory for the node chain</span>
DeletePtrList(ptrList);
<span class="code-comment">// wait for key press</span>
_fget<span class="code-keyword">char</span>();
}
}
<span class="code-keyword">return</span> 0;
}
<span class="code-comment">// read the next line from a file</span>
HRESULT ReadLine(FILE* file,<span class="code-keyword">char</span>* line,<span class="code-keyword">const</span> <span class="code-keyword">unsigned</span> <span class="code-keyword">int</span> size)
{
<span class="code-keyword">if</span>(feof(file)) <span class="code-keyword">return</span> E_FAIL;
<span class="code-keyword">return</span> NULL==fgets(line, size, file) ? E_FAIL:S_OK;
}
<span class="code-comment">// read the file into a chained list</span>
HRESULT ReadFile(<span class="code-keyword">const</span> <span class="code-keyword">char</span>* FName,<span class="code-keyword">struct</span> contact** ptrList)
{
FILE* fptr;
<span class="code-keyword">struct</span> contact* head;
<span class="code-keyword">struct</span> contact* newContact;
<span class="code-keyword">char</span>* sname, *fname, *phone,*company, *email;
<span class="code-keyword">char</span> line[60];
fptr = fopen(FName,<span class="code-string">"r"</span>);
<span class="code-keyword">if</span>(NULL==fptr)
{
printf(<span class="code-string">"\nCant open file!"</span>);
<span class="code-keyword">return</span> E_FAIL;
}
<span class="code-keyword">if</span>(!ptrList) <span class="code-keyword">return</span> E_POINTER; <span class="code-comment">// invalid result pointer</span>
<span class="code-comment">// get the trailing node</span>
<span class="code-keyword">for</span>(head=*ptrList;head&&head->next;head=head->next);
<span class="code-comment">// begin to read the next line</span>
<span class="code-keyword">while</span>(S_OK==ReadLine(fptr,line,<span class="code-keyword">sizeof</span>(line)/<span class="code-keyword">sizeof</span>(line[0])-2))
{
sname = strtok(line,<span class="code-string">","</span>);
fname = strtok(NULL,<span class="code-string">","</span>);
phone = strtok(NULL,<span class="code-string">","</span>);
company = strtok(NULL,<span class="code-string">","</span>);
email = strtok(NULL,<span class="code-string">","</span>);
<span class="code-comment">// create a new node</span>
newContact = (<span class="code-keyword">struct</span> contact *)malloc(<span class="code-keyword">sizeof</span>(<span class="code-keyword">struct</span> contact));
<span class="code-keyword">if</span>(!newContact) <span class="code-keyword">break</span>; <span class="code-comment">// out of memory</span>
<span class="code-comment">// chain the new node</span>
newContact->prev = head;
newContact->next = NULLPTR;
<span class="code-comment">//copy the data to the new one</span>
<span class="code-comment">// !! the strcpy() function is usafe - maybe buffer overruns.</span>
<span class="code-comment">// !! thats when the source length exceeds the target buffer size.</span>
strcpy(newContact->sname,sname);
strcpy(newContact->fname,fname);
strcpy(newContact->phone,phone);
strcpy(newContact->company,company);
strcpy(newContact->email,email);
<span class="code-comment">// chain the nodes</span>
<span class="code-keyword">if</span>(head) head->next = newContact;
<span class="code-comment">// head is the trailing node</span>
head = newContact;
<span class="code-comment">// set the result pointer</span>
<span class="code-keyword">if</span>(NULLPTR==*ptrList) *ptrList = head;
}
fclose(fptr);
<span class="code-keyword">return</span> head ? S_OK : E_FAIL <span class="code-comment">/* something wrong */</span>;
}
<span class="code-comment">// delete the chain elements</span>
<span class="code-keyword">void</span> DeletePtrList(<span class="code-keyword">struct</span> contact* ptrList)
{
<span class="code-keyword">struct</span> contact* head;
<span class="code-keyword">struct</span> contact* next;
<span class="code-keyword">for</span>(head = ptrList;head;head=next)
{
next = head->next;
free(head);
}
}
<span class="code-comment">// walk through the chain using a callback function</span>
<span class="code-keyword">void</span> WalkChain(<span class="code-keyword">struct</span> contact* ptrList,FNWALK fnwalk)
{
<span class="code-keyword">struct</span> contact* head;
<span class="code-keyword">for</span>(head = ptrList;head;head=head->next)
{
fnwalk(head);
}
}
Regards.
Regards.
这篇关于指针逻辑导致内存访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!