C编程字符串、指针和分配



我认为这个问题完全是内存分配不足的问题。

(也许跳到底部,阅读最后一个问题,获得一些简单的建议)

我正在编写这个程序来读取用户输入的文件。如果该文件"包括"其他文件,则它们也将被读取。为了检查另一个文件是否包含一个文件,我解析字符串的第一个单词。为此,我编写了一个函数,返回解析后的单词,并传入一个指针,该指针设置为下一个单词的第一个字母。例如,考虑字符串:

"include foo"注意文件只能包含1个其他文件

firstWord==包含,chPtr==f

我的算法解析firstWord以测试字符串是否与"include"相等,然后解析第二个单词以测试文件有效性,并查看文件是否已被读取。

现在,我的问题是,许多文件正在被读取,chPtr被覆盖。所以,当我将指针返回到下一个单词时。下一个单词有时会包含上一个文件的最后几个字符。考虑名为testfile-1和fake:的示例文件

让chPtr最初等于testfile-1,现在考虑解析"include false":

提取firstWord将==include,chPtr将被覆盖以指向false中的b。因此,chPtr将等于b o g u s’\0'l e-1。l e-1是testfile-1的最后几个字符,因为每次调用函数时chPtr都指向相同的内存地址。这对我来说是个问题,因为当我解析false时,chPtr会指向l。以下是我的函数代码:

char* extract_word(char** chPtr, char* line, char parseChar)      
//POST: word is returned as the first n characters read until parseChar occurs in line
//      FCTVAL == a ptr to the next word in line
{
   int i = 0;
   while(line[i] != parseChar && line[i] != '')                        
  {
     i++;
  }
  char* temp = Malloc(i + 1);            //I have a malloc wrapper to check validity
  for(int j = 0; j < i; j++)
  {
     temp[j] = line[j];
  }
  temp[i+1] = '';
  *chPtr = (line + i + 1);
  char* word = Strdup(temp);             //I have a wrapper for strdup too
  return word;

那么,我的问题诊断正确吗?如果是,我是否对chPtr进行深度复制?此外,我如何制作chPtr的深度副本?

非常感谢!

如果我理解正确,你想扫描一个文件,当遇到'include'指令时,你想无限次扫描'include'指示中指定的文件,以此类推,以获得任何级别的include,即读取一个可能包括其他文件的文件,而这些文件又可能包括其他的文件。。。。。

如果是这样的话(如果我错了,请纠正),那么这就是一个经典的递归问题。递归的优点是,所有变量都在堆栈上创建,并且在堆栈展开时自然释放。

以下代码将做到这一点,而不需要malloc或免费,也不需要复制任何东西:

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #define INCLUDE "include"
 #define INCOFFSET 7
 static void
 process_record (char *name, char *buf)
 {
   // process record here
   printf ("%s:%sn", name, buf);
 }
 // change this to detect your particular include
 static int
 isinclude (char *buf)
 {
   //printf ("%s:Record %s INCLUDE=%s INCOFFSET=%dn", __func__, buf, INCLUDE,
 //        INCOFFSET);
   if (!strncmp (buf, INCLUDE, INCOFFSET))
     {
       //printf ("%s:Record == include", __func__);
       return 1;
     }
   return 0;
 }
 static int
 read_file (char *name)
 {
   //printf ("%s:File %sn", __func__, name);
   FILE *fd = fopen (name, "r");
   if (!fd)
     {
       printf ("%s:Cannot open %sn", __func__, name);
       return -1;
     }
   char buf[1024];
   ssize_t n;
   while (fgets (buf, sizeof (buf), fd))
     {
       size_t n = strcspn (buf, "n");
       buf[n] = '';
       //printf ("%s:Buf %sn", __func__, buf);
       if (isinclude (buf))
         {
            read_file (buf + (INCOFFSET + 1));
         }
       else
         {
            process_record (name, buf);
         }
     }
   fclose (fd);
   return 0;
 }
 int
 main (int argc, char *argv[])
 {
   int ret = read_file (argv[1]);
   if (ret < 0)
     {
       exit (EXIT_FAILURE);
     }
   exit (EXIT_SUCCESS);
 }
char* temp = Malloc(i + 1);            //I have a malloc wrapper to check validity
for(int j = 0; j < i; j++)
{
   temp[j] = line[j];
}
temp[i+1] = '';  <------- subscript out of range replace with temp[i] = '';

不清楚你的问题在哪里。但你可以使用工具来帮助定位它。

Valgrind就是这样一种(免费)工具。它将检测各种内存访问错误。(它可能不会发现您的temp[i+1]='\0'错误,因为这不是"非常错误")。

我们的CheckPointer工具是另一个工具。它发现了Valgrind无法找到的错误(例如,它应该找到你的错误临时任务)。虽然它是商业性的,但评估版本处理的程序规模较小,可能对您有用。(我在家,不记得限制了)。

最新更新