Correct - all your struct type stores is the address of the first character in the string.  The string contents are stored "somewhere else" - in a string literal, in another dynamically-allocated block, in a static or auto array, etc.
You could declare everything auto:
void foo( void )
{
  char aStr[] = "this is not a test";
  Bar barInstance;
  barInstance.a = 51;
  barInstance.str = aStr;
  ...
}
You could allocate everything dynamically:
Bar *barInstance = malloc( sizeof *barInstance );
if ( barInstance )
{
  size_t size = strlen( "This is not a test" );
  barInstance->str = malloc( size + 1 );
  if ( barInstance->str )
    strcpy ( barInstance->str, "This is not a test" );
  ...
  /**
   * You must free barInstance->str before freeing
   * barInstance - just freeing barInstance won't
   * free the memory barInstance->str points to,
   * since that was a separate allocation.
   */
  free( barInstance->str );
  free( barInstance );
}
** Edit **
And there are other possibilities, but the point is that the string itself is stored separately from the struct instance.