从main使用malloc在函数中创建的字符串数组打印时出现问题

时间:2013-06-17 10:32:16

标签: c arrays malloc

为什么如果我在main函数中printf myarray[x]我没有数据(空白行)? 数组已正确填充(如果我在函数中打印我得到的值)

这是我的代码:

int main(void)  {
    char thisxpath[300];
    char thisurl[200];
    char** myarray = NULL;
    strcpy (thisurl,"http://api.openweathermap.org/data/2.5/weather?q=Pescara&mode=xml&units=metric");
    strcpy (thisxpath,"//city/@name | //country | //weather/@value | //temperature/@value | //precipitation/@value | //humidity/@value | //speed/@*[name()='name' or name()='value']");
    xmlretrive (thisurl, thisxpath, &myarray);

    printf("%s\n", myarray[1]);

    free(myarray);
    return 0;
}

void xmlretrive(char* myurl, char* myxpath, char** myarray) {

    //code that retrieve with cURL the XML and other stuff
    //keyword contain data, that are copied into myarray

    myarray = malloc(20 * sizeof(char*));   
    for (i=0; i < nodeset->nodeNr; i++) {
    keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
    myarray[i] = malloc((100) * sizeof(char));
    strcpy(myarray[i], keyword);
    // if I printf("%s\n", myarray[i]) here I can see that array is actually filled
    xmlFree(keyword);
}

1 个答案:

答案 0 :(得分:5)

您正在将myarray的副本传递给xmlretrive。如果要更改myarray指向xmlretrive内部的内容,则需要将指针传递给它。即char***

void xmlretrive(char* myurl, char* myxpath, char*** myarray) {
    *myarray = malloc(20 * sizeof(char*));   
    for (i=0; i < nodeset->nodeNr; i++) {
        keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
        (*myarray)[i] = malloc(strlen(keyword)+1);
        if ((*myarray)[i] == NULL) {
            // out of memory.  print error msg then exit
        }
        strcpy((*myarray)[i], keyword);
        xmlFree(keyword);
}

请注意,我还建议您对malloc行进行一些更改

  • shouldn't cast the return from malloc
  • 分配keyword所需字符串的确切长度,以避免strlen(keyword)>99缓冲区溢出的可能性
  • sizeof(char)保证为1,因此您无需将分配大小乘以它

这将解决您当前的问题,但可能不足以使事情正常运行。还需要考虑其他一些事项:

  • main需要为free的每个已分配成员以及myarray本身
  • 致电myarray
  • main您无法知道myarray的长度。{li>您可以将单独的length参数传递到xmlretrive或更改xmlretrive以在数组末尾添加NULL元素并迭代,直到您在{{1}中找到它为止}}
  • main应该为xmlretrive分配空间(+1假设您向数组添加nodeset->nodeNr + 1终结符)元素,而不是硬编码长度为20