浏览结构数组

时间:2012-05-02 15:13:23

标签: c memory-management segmentation-fault

我有一系列结构,每个结构都描述了我所谓的信号。我用这种方式声明了我的结构:

 /* Structure for keywords */
 struct varStruct
 {
    char* varName;
    int varOccurence;
 } signals[MAX_SIGNALS];

我正在循环中分析文件并动态查找信号声明,在我的情况下称为 newArrayName 。我想做的是,只有在尚未包含的情况下才将读取信号添加到阵列中。否则,我应该增加varOccurence变量。

这是我的代码,但我有分段错误(所以没有进一步的信息)......

    // We are in the loop that get the signals sequentially
    char* newArrayName = TheValueOfTheReadSignal.

    int i;
    // We browse all the array...
    for(i=0; i < MAX_SIGNALS; i++)
    {
        // If a signal already has the name of the currently-read signal, we inc its occurence
        if(strcmp(signals[i].varName, newArrayName) == 0)
        {
            signals[i].varOccurence++;
        }
        // Otherwise, we add a new signal with the read-name and an occurence corresponding to the value of a static variable that's incremented after each signal-reading.
        else
        {
            signals[index_Array].varName = newArrayName;
            signals[index_Array].varOccurence = index_Array;

        }
    }
     // We increment index_Array, which is a static int variable
       index_Array ++;
    // End of the loop that gets the signals 

导致分段错误。我的C语言不是很好,我甚至会说我很擅长。我的猜测是信号数组尚未初始化,因此signal [i]对他没有任何意义,但我不知道如何初始化一个结构数组。也许这是另一个原因,我不知道。

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:2)

问题是,在第一次迭代时,所有varName成员都将是NULL或未初始化的指针(取决于声明signals的位置)。确保它们已初始化为NULL

struct varStruct
{
    char* varName;
    int varOccurence;
} signals[MAX_SIGNALS] = { {0} };

在传递给NULL之前检查它是否为strcmp()

if(signals[i].varName && strcmp(signals[i].varName, newArrayName) == 0)

如果varName为NULL,则表示没有填充其他元素,您可以填充它并从循环中断开。

另外确保:

  • 分配给varName的值是动态分配的(例如,使用malloc())并且需要很长时间才能生效,记住free() varName时不再必需的。
  • 在填充index_Array元素之前,
  • MAX_SIGNALS小于signals

答案 1 :(得分:2)

  1. 您正在搜索循环中创建一个“新”条目。这几乎每次都会立即创建一个新的条目。您应该仅在所有现有条目不匹配后创建新条目;即你完成循环后。

  2. 你不应该循环到MAX_SIGNALS,因为在开始时,你的大部分数组都是空的。只有第一个index_Array元素是真实的。这也会让你用NULL指针初始化你的结构并检查它们,因为你无论如何也不会遍历未初始化的条目。

  3. 你盲目地递增index_Array。只有在确实添加条目时才会递增。

  4. 一些变化:

    // We are in the loop that get the signals sequentially
    char* newArrayName = TheValueOfTheReadSignal.
    
    int found_entry;
    found_entry = FALSE; /* A flag that remembers if the entry has been found.  */
    
    for(i=0; i < index_Array; i++)
    {
        if(strcmp(signals[i].varName, newArrayName) == 0)
        {
            signals[i].varOccurence++;
            found_entry = TRUE;
            break;
        }
    }
    if (!found_entry)
    {
        signals[index_Array].varName = newArrayName;
        signals[index_Array].varOccurence = index_Array++;
    }
    

答案 2 :(得分:1)

虽然您没有记录signals中的条目,或者当i大于记录条目数减去1时,strcmp(signals[i].varName, newArrayName)会尝试取消引用该无效条目(未初始化或{ {1}})指针NULL

除此之外,只要signals[i].varName变得与index_Array(或更大)一样大,

MAX_SIGNALS

你写过数组的末尾,这是未定义的行为,可能会直接导致内存损坏和/或分段错误,或者是内存损坏的结果。

在循环中,每次找到具有不同名称的信号时都会写入// We browse all the array... for(i=0; i < MAX_SIGNALS; i++) { // If a signal already has the name of the currently-read signal, we inc its occurence if(strcmp(signals[i].varName, newArrayName) == 0) { signals[i].varOccurence++; } // Otherwise, we add a new signal with the read-name and an occurence corresponding to the value of a static variable that's incremented after each signal-reading. else { signals[index_Array].varName = newArrayName; signals[index_Array].varOccurence = index_Array; } } // We increment index_Array, which is a static int variable index_Array ++; ,并且每次在循环运行后递增signals[index_Array],无论您是否已经有某些信号有这个名字与否。你应该检查你是否已经记录了信号,并且只有在没有写新条目并且增加index_Array的情况下:

index_Array