繁体   English   中英

C-我的代码有什么问题(malloc,char *)

[英]C - What's wrong with my code (malloc, char*)

我只想让您问一下这段代码我做错了什么。 我编写了一个在参数中带有char *的函数,我想直接对其进行修改而不返回smthg,并反转字符串。

#include <iostream>

void reverseString(char *p_string){

    int length = strlen(p_string);
    int r_it = length - 1;
    char* tmp = (char*)malloc(length);
    int last_it = 0;

    for (int i = 0; i != length; i++){
        tmp[i] = p_string[r_it];
        r_it--;
        last_it++;
    }
    tmp[last_it] = '\0';

    strcpy_s(p_string, length + 1, tmp);
    //free(tmp);
}

int main(){

    char str[] = "StackOverflow";

    reverseString(str);

    std::cout << str << std::endl;

    system("pause");
}

我已经习惯了C ++,并且不经常使用C函数,例如malloc / free / strcpy ...在这里,我的问题是,当我为临时char分配内存时,我在这里以length = 13的方式调用了Mallec(length)情况下,char = 1个字节,因此应该为13个char分配内存,对吗?

问题是分配了比需要更多的空间,因此我需要在我的strcpy_s之前使用“ \\ 0”,否则它不会中断。

我在某个地方犯错了吗? 另外,当我调用free(tmp)时,它也会中断并说堆损坏,但是在此之前我没有释放内存。

感谢您的帮助!

我使用了原始代码,并在malloc的大小上添加了一个简单的“ +1”,并获得了通过的结果。

不知道您的练习是否专门与malloc的使用有关,但是您是否考虑过直接在原始字符串中进行反转?

例如:

void reverseString(char *p_string){

    char* p_end = p_string+strlen(p_string)-1;
    char t;

    while (p_end > p_string)
    {
        t = *p_end;
        *p_end-- = *p_string;
        *p_string++ = t;
    }
}

int main(){

    char str[] = "StackOverflow";

    reverseString(str);

    std::cout << str << std::endl;

    system("pause");
}

如果需要使用malloc,则需要确保为包含'\\ 0'的字符串分配足够的空间。

您必须使用

int length = strlen(p_string);
int r_it = length - 1;
char* tmp = (char*)malloc(length+1);

由于strlen不会计算\\ 0字符。 因此,如果您不使用length + 1,这将失败:

tmp[last_it] = '\0';

C字符串的长度由终止的空字符确定:AC字符串的长度与字符串开头和终止的空字符之间的字符数一样长(不包括终止的空字符本身)。 http://www.cplusplus.com/reference/cstring/strlen/

顺便说一句。 C99支持半动态数组。 所以你可以尝试一下:

char tmp[length+1];

资料来源: http : //en.wikipedia.org/wiki/Variable-length_array

float read_and_process(int n)
{
    float vals[n];

    for (int i = 0; i < n; i++)
        vals[i] = read_val();
    return process(vals, n);
}

检查以下C代码:分配给tmp的内存应为length + 1,如下所示,并且还有许多不必要的变量可以避免。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void reverseString(char *p_string){

   int i;
   int length = strlen(p_string);
   int r_it = length - 1;
   char* tmp = (char*)malloc(length+1);

   for (i = 0; i != length; i++){
      tmp[i] = p_string[r_it--];
   }   
   tmp[i] = '\0';

   strcpy(p_string, tmp);
   return;

}

int main(){

   char str[] = "StackOverflow";

   reverseString(str);

   printf("%s",str);
   return 0;

}

您的方法从根本上没有什么错,只有一些细节。 由于我不确定您是如何发现sizeof(tmp)为32的,因此我将代码修改为以下代码,其中包括一些printf和一些小的更改:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

void reverseString(char *p_string)
{
  size_t length = strlen(p_string);
  size_t r_it = length - 1;
  char* tmp = (char*)malloc(length+1);
  int last_it = 0;
  size_t i=0;

  printf("strlen(p_string) = %d\n", strlen(p_string));
  printf("Before: strlen(tmp) = %d\n", strlen(tmp));

  for (i = 0; i != length; i++) {
    tmp[i] = p_string[r_it];
    r_it--;
    last_it++;
  }

  tmp[last_it] = '\0';

  printf("After: strlen(tmp) = %d\n", strlen(tmp));

  strcpy(p_string, tmp);

  free(tmp);
}

int main()
{
  char str[] = "StackOverflow";

  reverseString(str);

  printf("%s\n", str);

  return 0;
}

首先,我删除了所有C ++特定的代码-您现在可以使用gcc 运行以下代码将产生以下输出:

sizeof(p_string) = 13
Before: strlen(tmp) = 0
After: strlen(tmp) = 13
wolfrevOkcatS

这是可以预期的strlen基本上strlen数字节,直到它到达\\0字符为止,因此,第一次使用strlen打印大小时,由于我们刚刚分配了内存,因此它返回0。 正如另一个建议的那样,我们必须分配1个额外的字节来将\\0存储在新字符串中。

一旦完成反向操作,就会将13个字节复制到该内存中,并且第二个strlen返回预期的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM