(NASM,C)为什么你需要malloc两次来创建一个数组,如下所示

时间:2015-12-05 14:55:20

标签: c arrays pointers malloc nasm

char** names=(char**)malloc(count*sizeof(char*));
//while loop
names[count]=(char*)malloc(size+1);//why malloc again?

所以char** names=(char**)malloc(count*sizeof(char*));创建一个指向托管4 times count字节的位置的指针,然后将指针位置存储到名称中?

然后在while循环中,分配size+1个字节的长内存,并将其地址赋给names[count],它指的是names指向的位置?那么从第一个malloc创建的内存是否存储了第二个malloc创建的内存位置?并且内存指针的大小是4个字节,这样我可以通过从内存位置的开头移动到接下来的4个字节来访问每个names[count]吗?

如果我的想法是正确的,那么这两行c代码的这些正确的NASM实现是否正确:

;char** names=(char**)malloc(count*sizeof(char*));
  mov eax, dword count
  ;lea ebx, [eax*4]
  imul ebx, eax, 4
  push ebx
  call _malloc
  mov names, eax
  add esp, 4

;names[count]=(char*)malloc(size+1);
  mov ebx, size
inc ebx
push ebx
call _malloc
add esp,4
mov ebx, names
mov ecx, dword count
mov [ebx+ecx*4], eax

Fyi,这两行代码是以下c代码的一部分,用于从文件中提取名称并对其进行排序:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  char path[]="names.txt";

  char szName[50];

  int count=0;

  int size=0;

  int x=0;
  int y=0;

  char* temp=0;
  int pos=0;

  FILE* file=fopen(path,"rt");

  if (file){

  while (!feof(file)){

  fscanf(file,"%50s",szName);
  count++;


  }

  }
  else{
       printf("Error opening file\n");
       return 1;
  }

  printf ("Count: %d\n",count);

  char** names=(char**)malloc(count*sizeof(char*));

  rewind(file);

  count=0;



  while (!feof(file)){

  fscanf(file,"%50s",szName);

  size=strlen(szName);

  names[count]=(char*)malloc(size+1);

  strcpy(names[count],szName);

  count++;


  }

  printf("Original file\n");

  for (x=0;x<count;x++){

  printf("Name %d:\t%s\n",x+1,names[x]);

  }


  for (x=0;x<count;x++){

  temp=names[x];
  pos=x;

  for (y=x;y<count;y++){

      if (strcmp(temp,names[y])>0){

      temp=names[y];
      pos=y;

      }    
  }

  temp=names[x];
  names[x]=names[pos];
  names[pos]=temp;    
  }

  printf("Sorted names\n");

  for (x=0;x<count;x++){

  printf("Name %d:\t%s\n",x+1,names[x]);

  }

  system("PAUSE");  
  return 0;
}

2 个答案:

答案 0 :(得分:1)

  

所以char** names=(char**)malloc(count*sizeof(char*));创建一个指向某个位置的指针   托管4 times count个字节,然后将指针位置存储到名称?

是的,如果您所在环境中的sizeof(char*)4

  

然后在while循环中,分配size+1个字节长的内存并给出其地址   names[count],它指的是名称指向的位置?

formar部分是正确的,但后者是错误的。 该地址位于count指向的位置前面的names元素。

  

所以这里从第一个malloc创建的内存存储了第二个malloc创建的内存位置?

是的,确实如此。

  

并且内存指针的大小为4个字节,

这取决于环境。

  

这样我可以通过从内存位置的开头移动到接下来的4个字节来访问每个名称[count]?

是的,如果您所在环境中的sizeof(char*)4

  

如果我的想法是正确的,那么这两行c代码的这些正确的NASM实现是否正确:

如果您的环境中int是32位整数,我在代码中没有发现错误。

答案 1 :(得分:1)

你的教授正在创建一个字符串数组。写的代码不必要地混淆,但这个想法很合理。

这是希望不那么令人困惑的例子

// copy an existing string just like strdup()
char* stringDuplicate(const char* string) {
    size_t size = strlen(string) + 1; // 1 additional for `\0` terminator
    char* result = (char*)malloc(size * (sizeof(char)));
    strcpy(result, string);
    return result;
}

// copy an existing string array
char** stringArrayDuplicate(const char** stringArray, size_t size) {
    // Allocate an array which can hold size number of strings
    char** result = (char**)malloc(size * sizeof(char *));

    // For each string in stringArray, copy the string
    for (size_t i = 0; i < size; ++i) {
        result[i] = stringDuplicate(stringArray[i]);
    }

    return result;
}