问一个指向指针的指针的内存释放有关问题

问一个指向指针的指针的内存释放问题
举个例子说:
C/C++ code

int main(){
char **p1;
int i;
p1=(char **)malloc(sizeof(char)*20);
for(i=0;i<20;++i){
   p1[i]=(char *)malloc(sizeof(char)*10);
}
free(...);  //这里该怎么写?
return 0;
}


注释那里该怎么写?
for(i=0;i!=20;++i)
free(p1[i]);
free(p1);
这样写行吗? 还是直接free(p1)就行了?

------解决方案--------------------
楼主对指针的理解还不是很深刻.对二级指针的分配,首先需要分配一级指针,然后再为一级指针分配空间.楼主的意图可能是这样的:

C/C++ code
int main()
{
  int i;
  // 分配内存空间
  char** p2 = (char**)malloc(sizeof(char*)*20);
  for (i = 0; i < 20; ++i) {
    p2[i] = (char*)malloc(sizeof(char)*10);
  }

  // 使用p2[0], p2[1], ..., p2[19],每一个都是具有10个字符元素的字符数组
  
  // 准备释放内存空间
  for (i = 0; i < 20; ++ch) {
    free(p2[i]);  // 释放一级指针指向的内存
  }
  free(p2);       // 释放二级指针指向的内存
}