scanf()损坏了malloc区域

时间:2012-11-12 17:43:39

标签: c malloc

我的代码存在问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct hashTable{
char *data;
struct hashTable *next;
}HASHTABLE;

HASHTABLE **linkedHashTable[100];
void SaveHashTable1(char *str2,char *str3)          //s retazenim---Linked List
{
int hashResult;
HASHTABLE* linkedHashTableNode=NULL, *new_;

hashResult=StringToInt(str2);

if(linkedHashTable[hashResult]==NULL)
{
    linkedHashTableNode=(HASHTABLE*)malloc(sizeof(HASHTABLE));

    linkedHashTableNode->data=(char*)malloc(strlen(str3)*sizeof(char));
    strcpy(linkedHashTableNode->data,str3);

    linkedHashTableNode->next=NULL;
    linkedHashTable[hashResult]=&linkedHashTableNode;
}
else
{
    linkedHashTableNode=*linkedHashTable[hashResult];
    while(linkedHashTableNode->next!=NULL)
        linkedHashTableNode=linkedHashTableNode->next;

    new_=(HASHTABLE*)malloc(sizeof(HASHTABLE));

    new_->data=(char*)malloc(strlen(str3)*sizeof(char));
    strcpy(new_->data,str3);
    new_->next=NULL;
    linkedHashTableNode->next=new_;
}

 }
 int main(void)
 {
char *str1=NULL, *str2=NULL, *str3=NULL;
int i;


while(1)
{
    scanf("%s ", str1);
    if((strcmp(str1, "save"))==0)       //SAVE
    {
        scanf("%s %[^\n]s", str2, str3);

        SaveHashTable1(str2, str3);
    }
}
}

当我尝试执行此操作时,这是代码的一部分,我有问题:

linkedHashTableNode->data=(char*)malloc(strlen(str3)*sizeof(char));
strcpy(linkedHashTableNode->data,str3);

我总是在scanf()的内存区域附近得到内存空间,所以当我再次从控制台读取数据时,原始数据会被重写。我不知道哪里可能有问题。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

您未在malloc来电中请求足够的内存。 strlen告诉您字符串中有多少个字符,不包括终止NUL ,但strcpy无论如何都将复制终止NUL字符。

答案 1 :(得分:1)

在我看来,你有几个问题。

首先,scanf()函数可能有点冒险使用,因此您可能需要考虑修改main,以便使用gets()一次获取一行,然后解析输入行。然而,这不是一个表演者。

在main()中,您需要为str1,str2和str3分配内存。它们是你问题中指向NULL的指针。请参阅scanf man page

我建议您查看以下修改后的应用程序版本。仍然使用scanf()但是你应该考虑其他几个变化。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct hashTable{
    char  *data;
    struct hashTable *next;
}HASHTABLE;

HASHTABLE *linkedHashTable[100];

// stub version of StringToInt() so that it will compile and I can
// do a couple of simple tests in the debugger.
int StringToInt(char *str2)
{
    return 1;
}

void SaveHashTable1(char *str2,char *str3)          //s retazenim---Linked List
{
    int hashResult;
    HASHTABLE *new_;

    hashResult=StringToInt(str2);

    new_ = (HASHTABLE *)malloc(sizeof(HASHTABLE));
    if(linkedHashTable[hashResult] != NULL)
    {
        // since there is at least one entry in the table, lets traverse the list
        // until we reach the end.  we will then append our new entry onto the end.
        HASHTABLE *linkedHashTableNode;
        HASHTABLE *lastLinkedHashTableNode;

        linkedHashTableNode = linkedHashTable[hashResult];
        while(linkedHashTableNode != NULL) {
            lastLinkedHashTableNode = linkedHashTableNode;
            linkedHashTableNode = linkedHashTableNode->next;
        }
        lastLinkedHashTableNode->next = new_;
    } else {
        linkedHashTable[hashResult] = new_;
    }

    new_->data = (char *)malloc(strlen(str3) + 1);
    strcpy(new_->data, str3);
    new_->next=NULL;
}

int main(void)
{
    char  str1[128], str2[128], str3[128];

    while(1)
    {
        scanf("%s ", str1);
        if((strcmp(str1, "save"))==0)       //SAVE
        {
            scanf("%s %[^\n]s", str2, str3);
            SaveHashTable1(str2, str3);
        }
    }
}

答案 2 :(得分:0)

您应该注意到strlen("hello world") == 11但是“hello world需要存储char[12]

strlen(str3)会返回str3中的字符数,但不会计算'\0'

末尾的strlen3汽车数量

因此strcpy无法复制结束字符串caractere